* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc / src / .svn / text-base / enode.c.svn-base
blob760096dea356da1f6b0d6f8ee0ca753f4d63eda9
1 #include "c.h"
4 static Tree addtree(int, Tree, Tree);
5 static Tree andtree(int, Tree, Tree);
6 static Tree cmptree(int, Tree, Tree);
7 static int compatible(Type, Type);
8 static int isnullptr(Tree e);
9 static Tree multree(int, Tree, Tree);
10 static Tree subtree(int, Tree, Tree);
11 #define isvoidptr(ty) \
12         (isptr(ty) && unqual(ty->type) == voidtype)
14 Tree (*optree[])(int, Tree, Tree) = {
15 #define xx(a,b,c,d,e,f,g) e,
16 #define yy(a,b,c,d,e,f,g) e,
17 #include "token.h"
19 Tree call(Tree f, Type fty, Coordinate src) {
20         int n = 0;
21         Tree args = NULL, r = NULL, e;
22         Type *proto, rty = unqual(freturn(fty));
23         Symbol t3 = NULL;
25         if (fty->u.f.oldstyle)
26                 proto = NULL;
27         else
28                 proto = fty->u.f.proto;
29         if (hascall(f))
30                 r = f;
31         if (isstruct(rty))
32                 {
33                         t3 = temporary(AUTO, unqual(rty));
34                         if (rty->size == 0)
35                                 error("illegal use of incomplete type `%t'\n", rty);
36                 }
37         if (t != ')')
38                 for (;;) {
39                         Tree q = pointer(expr1(0));
40                         if (proto && *proto && *proto != voidtype)
41                                 {
42                                         Type aty;
43                                         q = value(q);
44                                         aty = assign(*proto, q);
45                                         if (aty)
46                                                 q = cast(q, aty);
47                                         else
48                                                 error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),
50                                                         q->type, *proto);
51                                         if ((isint(q->type) || isenum(q->type))
52                                         && q->type->size != inttype->size)
53                                                 q = cast(q, promote(q->type));
54                                         ++proto;
55                                 }
56                         else
57                                 {
58                                         if (!fty->u.f.oldstyle && *proto == NULL)
59                                                 error("too many arguments to %s\n", funcname(f));
60                                         q = value(q);
61                                         if (isarray(q->type) || q->type->size == 0)
62                                                 error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);
64                                         else
65                                                 q = cast(q, promote(q->type));
66                                 }
67                         if (!IR->wants_argb && isstruct(q->type)) {
68                                 if (iscallb(q))
69                                         q = addrof(q);
70                                 else {
71                                         Symbol t1 = temporary(AUTO, unqual(q->type));
72                                         q = asgn(t1, q);
73                                         q = tree(RIGHT, ptr(t1->type),
74                                                 root(q), lvalue(idtree(t1)));
75                                 }
76                         }
77                         if (q->type->size == 0)
78                                 q->type = inttype;
79                         if (hascall(q))
80                                 r = r ? tree(RIGHT, voidtype, r, q) : q;
81                         args = tree(mkop(ARG, q->type), q->type, q, args);
82                         n++;
83                         if (Aflag >= 2 && n == 32)
84                                 warning("more than 31 arguments in a call to %s\n",
85                                         funcname(f));
86                         if (t != ',')
87                                 break;
88                         t = gettok();
89                 }
90         expect(')');
91         if (proto && *proto && *proto != voidtype)
92                 error("insufficient number of arguments to %s\n",
93                         funcname(f));
94         if (r)
95                 args = tree(RIGHT, voidtype, r, args);
96         e = calltree(f, rty, args, t3);
97         if (events.calls)
98                 apply(events.calls, &src, &e);
99         return e;
101 Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
102         Tree p;
104         if (args)
105                 f = tree(RIGHT, f->type, args, f);
106         if (isstruct(ty))
107                 assert(t3),
108                 p = tree(RIGHT, ty,
109                         tree(CALL+B, ty, f, addrof(idtree(t3))),
110                         idtree(t3));
111         else {
112                 Type rty = ty;
113                 if (isenum(ty))
114                         rty = unqual(ty)->type;
115                 if (!isfloat(rty))
116                         rty = promote(rty);
117                 p = tree(mkop(CALL, rty), rty, f, NULL);
118                 if (isptr(ty) || p->type->size > ty->size)
119                         p = cast(p, ty);
120         }
121         return p;
123 Tree vcall(Symbol func, Type ty, ...) {
124         va_list ap;
125         Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;
127         assert(isfunc(func->type));
128         if (ty == NULL)
129                 ty = freturn(func->type);
130         va_start(ap, ty);
131         while ((e = va_arg(ap, Tree)) != NULL) {
132                 if (hascall(e))
133                         r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
134                 args = tree(mkop(ARG, e->type), e->type, e, args);
135         }
136         va_end(ap);
137         if (r != NULL)
138                 args = tree(RIGHT, voidtype, r, args);
139         return calltree(f, ty, args, NULL);
141 int iscallb(Tree e) {
142         return e->op == RIGHT && e->kids[0] && e->kids[1]
143                 && e->kids[0]->op == CALL+B
144                 && e->kids[1]->op == INDIR+B
145                 && isaddrop(e->kids[1]->kids[0]->op)
146                 && e->kids[1]->kids[0]->u.sym->temporary;
149 static Tree addtree(int op, Tree l, Tree r) {
150         Type ty = inttype;
152         if (isarith(l->type) && isarith(r->type)) {
153                 ty = binary(l->type, r->type);
154                 l = cast(l, ty);
155                 r = cast(r, ty);                
156         } else if (isptr(l->type) && isint(r->type))
157                 return addtree(ADD, r, l);
158         else if (  isptr(r->type) && isint(l->type)
159         && !isfunc(r->type->type))
160                 {
161                         long n;
162                         ty = unqual(r->type);
163                         n = unqual(ty->type)->size;
164                         if (n == 0)
165                                 error("unknown size for type `%t'\n", ty->type);
166                         l = cast(l, promote(l->type));
167                         if (n > 1)
168                                 l = multree(MUL, cnsttree(signedptr, n), l);
169                         if (YYcheck && !isaddrop(r->op))                /* omit */
170                                 return nullcall(ty, YYcheck, r, l);     /* omit */
171                         return simplify(ADD, ty, l, r);
172                 }
174         else
175                 typeerror(op, l, r);
176         return simplify(op, ty, l, r);
179 Tree cnsttree(Type ty, ...) {
180         Tree p = tree(mkop(CNST,ty), ty, NULL, NULL);
181         va_list ap;
183         va_start(ap, ty);
184         switch (ty->op) {
185         case INT:     p->u.v.i = va_arg(ap, long); break;
186         case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break;
187         case FLOAT:   p->u.v.d = va_arg(ap, double); break;
188         case POINTER: p->u.v.p = va_arg(ap, void *); break;
189         default: assert(0);
190         }
191         va_end(ap);
192         return p;
195 Tree consttree(unsigned n, Type ty) {
196         if (isarray(ty))
197                 ty = atop(ty);
198         else assert(isint(ty));
199         return cnsttree(ty, (unsigned long)n);
201 static Tree cmptree(int op, Tree l, Tree r) {
202         Type ty;
204         if (isarith(l->type) && isarith(r->type)) {
205                 ty = binary(l->type, r->type);
206                 l = cast(l, ty);
207                 r = cast(r, ty);
208         } else if (compatible(l->type, r->type)) {
209                 ty = unsignedptr;
210                 l = cast(l, ty);
211                 r = cast(r, ty);
212         } else {
213                 ty = unsignedtype;
214                 typeerror(op, l, r);
215         }
216         return simplify(mkop(op,ty), inttype, l, r);
218 static int compatible(Type ty1, Type ty2) {
219         return isptr(ty1) && !isfunc(ty1->type)
220             && isptr(ty2) && !isfunc(ty2->type)
221             && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
223 static int isnullptr(Tree e) {
224         Type ty = unqual(e->type);
226         return generic(e->op) == CNST
227             && ((ty->op == INT      && e->u.v.i == 0)
228              || (ty->op == UNSIGNED && e->u.v.u == 0)
229              || (isvoidptr(ty)      && e->u.v.p == NULL));
231 Tree eqtree(int op, Tree l, Tree r) {
232         Type xty = l->type, yty = r->type;
234         if ((isptr(xty) && isnullptr(r))
235         ||  (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty))
236         ||  (isptr(xty) && isptr(yty)
237             && eqtype(unqual(xty->type), unqual(yty->type), 1))) {
238                 Type ty = unsignedptr;
239                 l = cast(l, ty);
240                 r = cast(r, ty);
241                 return simplify(mkop(op,ty), inttype, l, r);
242         }
243         if ((isptr(yty) && isnullptr(l))
244         ||  (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty)))
245                 return eqtree(op, r, l);
246         return cmptree(op, l, r);
249 Type assign(Type xty, Tree e) {
250         Type yty = unqual(e->type);
252         xty = unqual(xty);
253         if (isenum(xty))
254                 xty = xty->type;
255         if (xty->size == 0 || yty->size == 0)
256                 return NULL;
257         if ( (isarith(xty) && isarith(yty))
258         ||  (isstruct(xty) && xty == yty))
259                 return xty;
260         if (isptr(xty) && isnullptr(e))
261                 return xty;
262         if (((isvoidptr(xty) && isptr(yty))
263           || (isptr(xty)     && isvoidptr(yty)))
264         && (  (isconst(xty->type)    || !isconst(yty->type))
265            && (isvolatile(xty->type) || !isvolatile(yty->type))))
266                 return xty;
268         if ((isptr(xty) && isptr(yty)
269             && eqtype(unqual(xty->type), unqual(yty->type), 1))
270         &&  (  (isconst(xty->type)    || !isconst(yty->type))
271             && (isvolatile(xty->type) || !isvolatile(yty->type))))
272                 return xty;
273         if (isptr(xty) && isptr(yty)
274         && (  (isconst(xty->type)    || !isconst(yty->type))
275            && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
276                 Type lty = unqual(xty->type), rty = unqual(yty->type);
277                 if ((isenum(lty) && rty == inttype)
278                 ||  (isenum(rty) && lty == inttype)) {
279                         if (Aflag >= 1)
280                                 warning("assignment between `%t' and `%t' is compiler-dependent\n",
281                                         xty, yty);
282                         return xty;
283                 }
284         }
285         return NULL;
287 Tree asgntree(int op, Tree l, Tree r) {
288         Type aty, ty;
290         r = pointer(r);
291         ty = assign(l->type, r);
292         if (ty)
293                 r = cast(r, ty);
294         else {
295                 typeerror(ASGN, l, r);
296                 if (r->type == voidtype)
297                         r = retype(r, inttype);
298                 ty = r->type;
299         }
300         if (l->op != FIELD)
301                 l = lvalue(l);
302         aty = l->type;
303         if (isptr(aty))
304                 aty = unqual(aty)->type;
305         if ( isconst(aty)
306         ||  (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) {
307                 if (isaddrop(l->op)
308                 && !l->u.sym->computed && !l->u.sym->generated)
309                         error("assignment to const identifier `%s'\n",
310                                 l->u.sym->name);
311                 else
312                         error("assignment to const location\n");
313         }
314         if (l->op == FIELD) {
315                 long n = 8*l->u.field->type->size - fieldsize(l->u.field);
316                 if (n > 0 && isunsigned(l->u.field->type))
317                         r = bittree(BAND, r,
318                                 cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
319                 else if (n > 0) {
320                         if (r->op == CNST+I) {
321                                 n = r->u.v.i;
322                                 if (n&(1<<(fieldsize(l->u.field)-1)))
323                                         n |= ~0UL<<fieldsize(l->u.field);
324                                 r = cnsttree(r->type, n);
325                         } else
326                                 r = shtree(RSH,
327                                         shtree(LSH, r, cnsttree(inttype, n)),
328                                         cnsttree(inttype, n));
329                 }
330         }
331         if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
332                 return tree(RIGHT, ty,
333                         tree(CALL+B, ty, r->kids[0]->kids[0], l),
334                         idtree(l->u.sym));
335         return tree(mkop(op,ty), ty, l, r);
337 Tree condtree(Tree e, Tree l, Tree r) {
338         Symbol t1;
339         Type ty, xty = l->type, yty = r->type;
340         Tree p;
342         if (isarith(xty) && isarith(yty))
343                 ty = binary(xty, yty);
344         else if (eqtype(xty, yty, 1))
345                 ty = unqual(xty);
346         else if (isptr(xty)   && isnullptr(r))
347                 ty = xty;
348         else if (isnullptr(l) && isptr(yty))
349                 ty = yty;
350         else if ((isptr(xty) && !isfunc(xty->type) && isvoidptr(yty))
351         ||       (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty)))
352                 ty = voidptype;
353         else if ((isptr(xty) && isptr(yty)
354                  && eqtype(unqual(xty->type), unqual(yty->type), 1)))
355                 ty = xty;
356         else {
357                 typeerror(COND, l, r);
358                 return consttree(0, inttype);
359         }
360         if (isptr(ty)) {
361                 ty = unqual(unqual(ty)->type);
362                 if ((isptr(xty) && isconst(unqual(xty)->type))
363                 ||  (isptr(yty) && isconst(unqual(yty)->type)))
364                         ty = qual(CONST, ty);
365                 if ((isptr(xty) && isvolatile(unqual(xty)->type))
366                 ||  (isptr(yty) && isvolatile(unqual(yty)->type)))
367                         ty = qual(VOLATILE, ty);
368                 ty = ptr(ty);
369         }
370         switch (e->op) {
371         case CNST+I: return cast(e->u.v.i != 0   ? l : r, ty);
372         case CNST+U: return cast(e->u.v.u != 0   ? l : r, ty);
373         case CNST+P: return cast(e->u.v.p != 0   ? l : r, ty);
374         case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty);
375         }
376         if (ty != voidtype && ty->size > 0) {
377                 t1 = genident(REGISTER, unqual(ty), level);
378         /*      t1 = temporary(REGISTER, unqual(ty)); */
379                 l = asgn(t1, l);
380                 r = asgn(t1, r);
381         } else
382                 t1 = NULL;
383         p = tree(COND, ty, cond(e),
384                 tree(RIGHT, ty, root(l), root(r)));
385         p->u.sym = t1;
386         return p;
388 /* addrof - address of p */
389 Tree addrof(Tree p) {
390         Tree q = p;
392         for (;;)
393                 switch (generic(q->op)) {
394                 case RIGHT:
395                         assert(q->kids[0] || q->kids[1]);
396                         q = q->kids[1] ? q->kids[1] : q->kids[0];
397                         continue;
398                 case ASGN:
399                         q = q->kids[1];
400                         continue;
401                 case COND: {
402                         Symbol t1 = q->u.sym;
403                         q->u.sym = 0;
404                         q = idtree(t1);
405                         /* fall thru */
406                         }
407                 case INDIR:
408                         if (p == q)
409                                 return q->kids[0];
410                         q = q->kids[0];
411                         return tree(RIGHT, q->type, root(p), q);
412                 default:
413                         error("addressable object required\n");
414                         return value(p);
415                 }
418 /* andtree - construct tree for l [&& ||] r */
419 static Tree andtree(int op, Tree l, Tree r) {
420         if (!isscalar(l->type) || !isscalar(r->type))
421                 typeerror(op, l, r);
422         return simplify(op, inttype, cond(l), cond(r));
425 /* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
426 Tree asgn(Symbol p, Tree e) {
427         if (isarray(p->type))
428                 e = tree(ASGN+B, p->type, idtree(p),
429                         tree(INDIR+B, e->type, e, NULL));
430         else {
431                 Type ty = p->type;
432                 p->type = unqual(p->type);
433                 if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
434                         p->type->u.sym->u.s.cfields = 0;
435                         e = asgntree(ASGN, idtree(p), e);
436                         p->type->u.sym->u.s.cfields = 1;
437                 } else
438                         e = asgntree(ASGN, idtree(p), e);
439                 p->type = ty;
440         }
441         return e;
444 /* bittree - construct tree for l [& | ^ %] r */
445 Tree bittree(int op, Tree l, Tree r) {
446         Type ty = inttype;
448         if (isint(l->type) && isint(r->type)) {
449                 ty = binary(l->type, r->type);
450                 l = cast(l, ty);
451                 r = cast(r, ty);                
452         } else
453                 typeerror(op, l, r);
454         return simplify(op, ty, l, r);
457 /* multree - construct tree for l [* /] r */
458 static Tree multree(int op, Tree l, Tree r) {
459         Type ty = inttype;
461         if (isarith(l->type) && isarith(r->type)) {
462                 ty = binary(l->type, r->type);
463                 l = cast(l, ty);
464                 r = cast(r, ty);                
465         } else
466                 typeerror(op, l, r);
467         return simplify(op, ty, l, r);
470 /* shtree - construct tree for l [>> <<] r */
471 Tree shtree(int op, Tree l, Tree r) {
472         Type ty = inttype;
474         if (isint(l->type) && isint(r->type)) {
475                 ty = promote(l->type);
476                 l = cast(l, ty);
477                 r = cast(r, inttype);
478         } else
479                 typeerror(op, l, r);
480         return simplify(op, ty, l, r);
483 /* subtree - construct tree for l - r */
484 static Tree subtree(int op, Tree l, Tree r) {
485         long n;
486         Type ty = inttype;
488         if (isarith(l->type) && isarith(r->type)) {
489                 ty = binary(l->type, r->type);
490                 l = cast(l, ty);
491                 r = cast(r, ty);                
492         } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
493                 ty = unqual(l->type);
494                 n = unqual(ty->type)->size;
495                 if (n == 0)
496                         error("unknown size for type `%t'\n", ty->type);
497                 r = cast(r, promote(r->type));
498                 if (n > 1)
499                         r = multree(MUL, cnsttree(signedptr, n), r);
500                 if (isunsigned(r->type))
501                         r = cast(r, unsignedptr);
502                 else
503                         r = cast(r, signedptr);
504                 return simplify(SUB+P, ty, l, r);
505         } else if (compatible(l->type, r->type)) {
506                 ty = unqual(l->type);
507                 n = unqual(ty->type)->size;
508                 if (n == 0)
509                         error("unknown size for type `%t'\n", ty->type);
510                 l = simplify(SUB+U, unsignedptr,
511                         cast(l, unsignedptr), cast(r, unsignedptr));
512                 return simplify(DIV+I, longtype,
513                         cast(l, longtype), cnsttree(longtype, n));
514         } else
515                 typeerror(op, l, r);
516         return simplify(op, ty, l, r);
519 /* typeerror - issue "operands of op have illegal types `l' and `r'" */
520 void typeerror(int op, Tree l, Tree r) {
521         int i;
522         static struct { int op; char *name; } ops[] = {
523                 {ASGN, "="},    {INDIR, "*"},   {NEG,  "-"},
524                 {ADD,  "+"},    {SUB,   "-"},   {LSH,  "<<"},
525                 {MOD,  "%"},    {RSH,   ">>"},  {BAND, "&"},
526                 {BCOM, "~"},    {BOR,   "|"},   {BXOR, "^"},
527                 {DIV,  "/"},    {MUL,   "*"},   {EQ,   "=="},
528                 {GE,   ">="},   {GT,    ">"},   {LE,   "<="},
529                 {LT,   "<"},    {NE,    "!="},  {AND,  "&&"},
530                 {NOT,  "!"},    {OR,    "||"},  {COND, "?:"},
531                 {0, 0}
532         };
534         op = generic(op);
535         for (i = 0; ops[i].op; i++)
536                 if (op == ops[i].op)
537                         break;
538         assert(ops[i].name);
539         if (r)
540                 error("operands of %s have illegal types `%t' and `%t'\n",
541                         ops[i].name, l->type, r->type);
542         else
543                 error("operand of unary %s has illegal type `%t'\n", ops[i].name,
544                         l->type);