* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc / src / .svn / text-base / expr.c.svn-base
blobb8cb08b614eb8c9ad5a9dbb6aadf71f26dc6cc1c
1 #include "c.h"
4 static char prec[] = {
5 #define xx(a,b,c,d,e,f,g) c,
6 #define yy(a,b,c,d,e,f,g) c,
7 #include "token.h"
8 };
9 static int oper[] = {
10 #define xx(a,b,c,d,e,f,g) d,
11 #define yy(a,b,c,d,e,f,g) d,
12 #include "token.h"
14 float refinc = 1.0;
15 static Tree expr2(void);
16 static Tree expr3(int);
17 static Tree nullcheck(Tree);
18 static Tree postfix(Tree);
19 static Tree unary(void);
20 static Tree primary(void);
21 static Type super(Type ty);
23 static Type super(Type ty) {
24         switch (ty->op) {
25         case INT:
26                 if (ty->size < inttype->size)
27                         return inttype;
28                 break;
29         case UNSIGNED:
30                 if (ty->size < unsignedtype->size)
31                         return unsignedtype;
32                 break;
33         case POINTER:
34                 return unsignedptr;
35         }
36         return ty;
38 Tree expr(int tok) {
39         static char stop[] = { IF, ID, '}', 0 };
40         Tree p = expr1(0);
42         while (t == ',') {
43                 Tree q;
44                 t = gettok();
45                 q = pointer(expr1(0));
46                 p = tree(RIGHT, q->type, root(value(p)), q);
47         }
48         if (tok)        
49                 test(tok, stop);
50         return p;
52 Tree expr0(int tok) {
53         return root(expr(tok));
55 Tree expr1(int tok) {
56         static char stop[] = { IF, ID, 0 };
57         Tree p = expr2();
59         if (t == '='
60         || (prec[t] >=  6 && prec[t] <=  8)
61         || (prec[t] >= 11 && prec[t] <= 13)) {
62                 int op = t;
63                 t = gettok();
64                 if (oper[op] == ASGN)
65                         p = asgntree(ASGN, p, value(expr1(0)));
66                 else
67                         {
68                                 expect('=');
69                                 p = incr(op, p, expr1(0));
70                         }
71         }
72         if (tok)        
73                 test(tok, stop);
74         return p;
76 Tree incr(int op, Tree v, Tree e) {
77         return asgntree(ASGN, v, (*optree[op])(oper[op], v, e));
79 static Tree expr2(void) {
80         Tree p = expr3(4);
82         if (t == '?') {
83                 Tree l, r;
84                 Coordinate pts[2];
85                 if (Aflag > 1 && isfunc(p->type))
86                         warning("%s used in a conditional expression\n",
87                                 funcname(p));
88                 p = pointer(p);
89                 t = gettok();
90                 pts[0] = src;
91                 l = pointer(expr(':'));
92                 pts[1] = src;
93                 r = pointer(expr2());
94                 if (events.points)
95                         {
96                                 apply(events.points, &pts[0], &l);
97                                 apply(events.points, &pts[1], &r);
98                         }
99                 p = condtree(p, l, r);
100         }
101         return p;
103 Tree value(Tree p) {
104         int op = generic(rightkid(p)->op);
106         if (p->type != voidtype
107         && (op==AND || op==OR || op==NOT || op==EQ || op==NE
108         ||  op== LE || op==LT || op== GE || op==GT))
109                 p = condtree(p, consttree(1, inttype),
110                         consttree(0, inttype));
111         return p;
113 static Tree expr3(int k) {
114         int k1;
115         Tree p = unary();
117         for (k1 = prec[t]; k1 >= k; k1--)
118                 while (prec[t] == k1 && *cp != '=') {
119                         Tree r;
120                         Coordinate pt;
121                         int op = t;
122                         t = gettok();
123                         pt = src;
124                         p = pointer(p);
125                         if (op == ANDAND || op == OROR) {
126                                 r = pointer(expr3(k1));
127                                 if (events.points)
128                                         apply(events.points, &pt, &r);
129                         } else
130                                 r = pointer(expr3(k1 + 1));
131                         p = (*optree[op])(oper[op], p, r); 
132                 }
133         return p;
135 static Tree unary(void) {
136         Tree p;
138         switch (t) {
139         case '*':    t = gettok(); p = unary(); p = pointer(p);
140                                                   if (isptr(p->type)
141                                                   && (isfunc(p->type->type) || isarray(p->type->type)))
142                                                         p = retype(p, p->type->type);
143                                                   else {
144                                                         if (YYnull)
145                                                                 p = nullcheck(p);
146                                                         p = rvalue(p);
147                                                   } break;
148         case '&':    t = gettok(); p = unary(); if (isarray(p->type) || isfunc(p->type))
149                                                         p = retype(p, ptr(p->type));
150                                                   else
151                                                         p = lvalue(p);
152                                                   if (isaddrop(p->op) && p->u.sym->sclass == REGISTER)
153                                                         error("invalid operand of unary &; `%s' is declared register\n", p->u.sym->name);
155                                                   else if (isaddrop(p->op))
156                                                         p->u.sym->addressed = 1;
157  break;
158         case '+':    t = gettok(); p = unary(); p = pointer(p);
159                                                   if (isarith(p->type))
160                                                         p = cast(p, promote(p->type));
161                                                   else
162                                                         typeerror(ADD, p, NULL);  break;
163         case '-':    t = gettok(); p = unary(); p = pointer(p);
164                                                   if (isarith(p->type)) {
165                                                         Type ty = promote(p->type);
166                                                         p = cast(p, ty);
167                                                         if (isunsigned(ty)) {
168                                                                 warning("unsigned operand of unary -\n");
169                                                                 p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL));
170                                                         } else
171                                                                 p = simplify(NEG, ty, p, NULL);
172                                                   } else
173                                                         typeerror(SUB, p, NULL); break;
174         case '~':    t = gettok(); p = unary(); p = pointer(p);
175                                                   if (isint(p->type)) {
176                                                         Type ty = promote(p->type);
177                                                         p = simplify(BCOM, ty, cast(p, ty), NULL);
178                                                   } else
179                                                         typeerror(BCOM, p, NULL);  break;
180         case '!':    t = gettok(); p = unary(); p = pointer(p);
181                                                   if (isscalar(p->type))
182                                                         p = simplify(NOT, inttype, cond(p), NULL);
183                                                   else
184                                                         typeerror(NOT, p, NULL); break;
185         case INCR:   t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break;
186         case DECR:   t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break;
187         case TYPECODE: case SIZEOF: { int op = t;
188                                       Type ty;
189                                       p = NULL;
190                                       t = gettok();
191                                       if (t == '(') {
192                                         t = gettok();
193                                         if (istypename(t, tsym)) {
194                                                 ty = typename();
195                                                 expect(')');
196                                         } else {
197                                                 p = postfix(expr(')'));
198                                                 ty = p->type;
199                                         }
200                                       } else {
201                                         p = unary();
202                                         ty = p->type;
203                                       }
204                                       assert(ty);
205                                       if (op == TYPECODE)
206                                         p = cnsttree(inttype, (long)ty->op);
207                                       else {
208                                         if (isfunc(ty) || ty->size == 0)
209                                                 error("invalid type argument `%t' to `sizeof'\n", ty);
210                                         else if (p && rightkid(p)->op == FIELD)
211                                                 error("`sizeof' applied to a bit field\n");
212                                         p = cnsttree(unsignedlong, (unsigned long)ty->size);
213                                       } } break;
214         case '(':
215                 t = gettok();
216                 if (istypename(t, tsym)) {
217                         Type ty, ty1 = typename(), pty;
218                         expect(')');
219                         ty = unqual(ty1);
220                         if (isenum(ty)) {
221                                 Type ty2 = ty->type;
222                                 if (isconst(ty1))
223                                         ty2 = qual(CONST, ty2);
224                                 if (isvolatile(ty1))
225                                         ty2 = qual(VOLATILE, ty2);
226                                 ty1 = ty2;
227                                 ty = ty->type;
228                         }
229                         p = pointer(unary());
230                         pty = p->type;
231                         if (isenum(pty))
232                                 pty = pty->type;
233                         if ((isarith(pty) && isarith(ty))
234                         ||  (isptr(pty)   && isptr(ty))) {
235                                 explicitCast++;
236                                 p = cast(p, ty);
237                                 explicitCast--;
238                         } else if ((isptr(pty) && isint(ty))
239                         ||       (isint(pty) && isptr(ty))) {
240                                 if (Aflag >= 1 && ty->size < pty->size)
241                                         warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, ty);
243                                 p = cast(p, ty);
244                         } else if (ty != voidtype) {
245                                 error("cast from `%t' to `%t' is illegal\n",
246                                         p->type, ty1);
247                                 ty1 = inttype;
248                         }
249                         if (generic(p->op) == INDIR || ty->size == 0)
250                                 p = tree(RIGHT, ty1, NULL, p);
251                         else
252                                 p = retype(p, ty1);
253                 } else
254                         p = postfix(expr(')'));
255                 break;
256         default:
257                 p = postfix(primary());
258         }
259         return p;
262 static Tree postfix(Tree p) {
263         for (;;)
264                 switch (t) {
265                 case INCR:  p = tree(RIGHT, p->type,
266                                 tree(RIGHT, p->type,
267                                         p,
268                                         incr(t, p, consttree(1, inttype))),
269                                 p);
270                             t = gettok(); break;
271                 case DECR:  p = tree(RIGHT, p->type,
272                                 tree(RIGHT, p->type,
273                                         p,
274                                         incr(t, p, consttree(1, inttype))),
275                                 p);
276                             t = gettok(); break;
277                 case '[':   {
278                                 Tree q;
279                                 t = gettok();
280                                 q = expr(']');
281                                 if (YYnull) {
282                                         if (isptr(p->type))
283                                                 p = nullcheck(p);
284                                         else if (isptr(q->type))
285                                                 q = nullcheck(q);
286                                 }
287                                 p = (*optree['+'])(ADD, pointer(p), pointer(q));
288                                 if (isptr(p->type) && isarray(p->type->type))
289                                         p = retype(p, p->type->type);
290                                 else
291                                         p = rvalue(p);
292                             } break;
293                 case '(':   {
294                                 Type ty;
295                                 Coordinate pt;
296                                 p = pointer(p);
297                                 if (isptr(p->type) && isfunc(p->type->type))
298                                         ty = p->type->type;
299                                 else {
300                                         error("found `%t' expected a function\n", p->type);
301                                         ty = func(voidtype, NULL, 1);
302                                         p = retype(p, ptr(ty));
303                                 }
304                                 pt = src;
305                                 t = gettok();
306                                 p = call(p, ty, pt);
307                             } break;
308                 case '.':   t = gettok();
309                             if (t == ID) {
310                                 if (isstruct(p->type)) {
311                                         Tree q = addrof(p);
312                                         p = field(q, token);
313                                         q = rightkid(q);
314                                         if (isaddrop(q->op) && q->u.sym->temporary)
315                                                 p = tree(RIGHT, p->type, p, NULL);
316                                 } else
317                                         error("left operand of . has incompatible type `%t'\n",
318                                                 p->type);
319                                 t = gettok();
320                             } else
321                                 error("field name expected\n"); break;
322                 case DEREF: t = gettok();
323                             p = pointer(p);
324                             if (t == ID) {
325                                 if (isptr(p->type) && isstruct(p->type->type)) {
326                                         if (YYnull)
327                                                 p = nullcheck(p);
328                                         p = field(p, token);
329                                 } else
330                                         error("left operand of -> has incompatible type `%t'\n", p->type);
332                                 t = gettok();
333                             } else
334                                 error("field name expected\n"); break;
335                 default:
336                         return p;
337                 }
339 static Tree primary(void) {
340         Tree p;
342         assert(t != '(');
343         switch (t) {
344         case ICON:
345         case FCON: p = tree(mkop(CNST,tsym->type), tsym->type, NULL, NULL);
346                    p->u.v = tsym->u.c.v;
347  break;
348         case SCON: if (ischar(tsym->type->type))
349                         tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size);
350                    else
351                         tsym->u.c.v.p = memcpy(allocate(tsym->type->size, PERM), tsym->u.c.v.p, tsym->type->size);
352                    tsym = constant(tsym->type, tsym->u.c.v); 
353                    if (tsym->u.c.loc == NULL)
354                         tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL);
355                    p = idtree(tsym->u.c.loc); break;
356         case ID:   if (tsym == NULL)
357                         {
358                                 Symbol p = install(token, &identifiers, level, FUNC);
359                                 p->src = src;
360                                 if (getchr() == '(') {
361                                         Symbol q = lookup(token, externals);
362                                         p->type = func(inttype, NULL, 1);
363                                         p->sclass = EXTERN;
364                                         if (Aflag >= 1)
365                                                 warning("missing prototype\n");
366                                         if (q && !eqtype(q->type, p->type, 1))
367                                                 warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src);
369                                         if (q == NULL) {
370                                                 q = install(p->name, &externals, GLOBAL, PERM);
371                                                 q->type = p->type;
372                                                 q->sclass = EXTERN;
373                                                 q->src = src;
374                                                 (*IR->defsymbol)(q);
375                                         }
376                                         p->u.alias = q;
377                                 } else {
378                                         error("undeclared identifier `%s'\n", p->name);
379                                         p->sclass = AUTO;
380                                         p->type = inttype;
381                                         if (p->scope == GLOBAL)
382                                                 (*IR->defsymbol)(p);
383                                         else
384                                                 addlocal(p);
385                                 }
386                                 t = gettok();
387                                 if (xref)
388                                         use(p, src);
389                                 return idtree(p);
390                         }
391                    if (xref)
392                         use(tsym, src);
393                    if (tsym->sclass == ENUM)
394                         p = consttree(tsym->u.value, inttype);
395                    else {
396                         if (tsym->sclass == TYPEDEF)
397                                 error("illegal use of type name `%s'\n", tsym->name);
398                         p = idtree(tsym);
399                    } break;
400         case FIRSTARG:
401                 if (level > PARAM && cfunc && cfunc->u.f.callee[0])
402                         p = idtree(cfunc->u.f.callee[0]);
403                 else {
404                         error("illegal use of `%k'\n", FIRSTARG);
405                         p = cnsttree(inttype, 0L);
406                 }
407                 break;
408         default:
409                 error("illegal expression\n");
410                         p = cnsttree(inttype, 0L);
411         }
412         t = gettok();
413         return p;
415 Tree idtree(Symbol p) {
416         int op;
417         Tree e;
418         Type ty = p->type ? unqual(p->type) : voidptype;
420         if (p->scope == GLOBAL || p->sclass == STATIC)
421                 op = ADDRG;
422         else if (p->scope == PARAM) {
423                 op = ADDRF;
424                 if (isstruct(p->type) && !IR->wants_argb)
425                         {
426                                 e = tree(mkop(op,voidptype), ptr(ptr(p->type)), NULL, NULL);
427                                 e->u.sym = p;
428                                 return rvalue(rvalue(e));
429                         }
430         } else if (p->sclass == EXTERN) {
431                 assert(p->u.alias);
432                 p = p->u.alias;
433                 op = ADDRG;
434         } else
435                 op = ADDRL;
436         p->ref += refinc;
437         if (isarray(ty))
438                 e = tree(mkop(op,voidptype), p->type,      NULL, NULL);
439         else if (isfunc(ty))
440                 e = tree(mkop(op,funcptype), p->type,      NULL, NULL);
441         else
442                 e = tree(mkop(op,voidptype), ptr(p->type), NULL, NULL);
443         e->u.sym = p;
444         if (isptr(e->type))
445                 e = rvalue(e);
446         return e;
449 Tree rvalue(Tree p) {
450         Type ty = deref(p->type);
452         ty = unqual(ty);
453         return tree(mkop(INDIR,ty), ty, p, NULL);
455 Tree lvalue(Tree p) {
456         if (generic(p->op) != INDIR) {
457                 error("lvalue required\n");
458                 return value(p);
459         } else if (unqual(p->type) == voidtype)
460                 warning("`%t' used as an lvalue\n", p->type);
461         return p->kids[0];
463 Tree retype(Tree p, Type ty) {
464         Tree q;
466         if (p->type == ty)
467                 return p;
468         q = tree(p->op, ty, p->kids[0], p->kids[1]);
469         q->node = p->node;
470         q->u = p->u;
471         return q;
473 Tree rightkid(Tree p) {
474         while (p && p->op == RIGHT)
475                 if (p->kids[1])
476                         p = p->kids[1];
477                 else if (p->kids[0])
478                         p = p->kids[0];
479                 else
480                         assert(0);
481         assert(p);
482         return p;
484 int hascall(Tree p) {
485         if (p == 0)
486                 return 0;
487         if (generic(p->op) == CALL || (IR->mulops_calls &&
488           (p->op == DIV+I || p->op == MOD+I || p->op == MUL+I
489         || p->op == DIV+U || p->op == MOD+U || p->op == MUL+U)))
490                 return 1;
491         return hascall(p->kids[0]) || hascall(p->kids[1]);
493 Type binary(Type xty, Type yty) {
494 #define xx(t) if (xty == t || yty == t) return t
495         xx(longdouble);
496         xx(doubletype);
497         xx(floattype);
498         xx(unsignedlonglong);
499         xx(longlong);
500         xx(unsignedlong);
501         if ((xty == longtype     && yty == unsignedtype)
502         ||  (xty == unsignedtype && yty == longtype)) {
503                 if (longtype->size > unsignedtype->size)
504                         return longtype;
505                 else
506                         return unsignedlong;
507         }
508         xx(longtype);
509         xx(unsignedtype);
510         return inttype;
511 #undef xx
513 Tree pointer(Tree p) {
514         if (isarray(p->type))
515                 /* assert(p->op != RIGHT || p->u.sym == NULL), */
516                 p = retype(p, atop(p->type));
517         else if (isfunc(p->type))
518                 p = retype(p, ptr(p->type));
519         return p;
521 Tree cond(Tree p) {
522         int op = generic(rightkid(p)->op);
524         if (op == AND || op == OR || op == NOT
525         ||  op == EQ  || op == NE
526         ||  op == LE  || op == LT || op == GE || op == GT)
527                 return p;
528         p = pointer(p);
529         return (*optree[NEQ])(NE, p, consttree(0, inttype));
531 Tree cast(Tree p, Type type) {
532         Type src, dst;
534         p = value(p);
535         if (p->type == type)
536                 return p;
537         dst = unqual(type);
538         src = unqual(p->type);
539         if (src->op != dst->op || src->size != dst->size) {
540                 switch (src->op) {
541                 case INT:
542                         if (src->size < inttype->size)
543                                 p = simplify(CVI, inttype, p, NULL);
544                         break;
545                 case UNSIGNED:
546                         if (src->size < inttype->size)
547                                 p = simplify(CVU, inttype, p, NULL);
548                         else if (src->size < unsignedtype->size)
549                                 p = simplify(CVU, unsignedtype, p, NULL);
550                         break;
551                 case ENUM:
552                         p = retype(p, inttype);
553                         break;
554                 case POINTER:
555                         if (isint(dst) && src->size > dst->size)
556                                 warning("conversion from `%t' to `%t' is undefined\n", p->type, type);
557                         p = simplify(CVP, super(src), p, NULL);
558                         break;
559                 case FLOAT:
560                         break;
561                 default: assert(0);
562                 }
563                 {
564                         src = unqual(p->type);
565                         dst = super(dst);
566                         if (src->op != dst->op)
567                                 switch (src->op) {
568                                 case INT:
569                                         p = simplify(CVI, dst, p, NULL);
570                                         break;
571                                 case UNSIGNED:
572                                         if (isfloat(dst)) {
573                                                 Type ssrc = signedint(src);
574                                                 Tree two = cnsttree(longdouble, (double)2.0);
575                                                 p = (*optree['+'])(ADD,
576                                                         (*optree['*'])(MUL,
577                                                                 two,
578                                                                 simplify(CVU, ssrc,
579                                                                         simplify(RSH, src,
580                                                                                 p, consttree(1, inttype)), NULL)),
581                                                         simplify(CVU, ssrc,
582                                                                 simplify(BAND, src,
583                                                                         p, consttree(1, unsignedtype)), NULL));
584                                         } else
585                                                 p = simplify(CVU, dst, p, NULL);
586                                         break;
587                                 case FLOAT:
588                                         if (isunsigned(dst)) {
589                                                 Type sdst = signedint(dst);
590                                                 Tree c = cast(cnsttree(longdouble, (double)sdst->u.sym->u.limits.max.i + 1), src);
591                                                 p = condtree(
592                                                         simplify(GE, src, p, c),
593                                                         (*optree['+'])(ADD,
594                                                                 cast(cast(simplify(SUB, src, p, c), sdst), dst),
595                                                                 cast(cnsttree(unsignedlong, (unsigned long)sdst->u.sym->u.limits.max.i + 1), dst)),
596                                                         simplify(CVF, sdst, p, NULL));
597                                         } else
598                                                 p = simplify(CVF, dst, p, NULL);
599                                         break;
600                                 default: assert(0);
601                                 }
602                         dst = unqual(type);
603                 }
604         }
605         src = unqual(p->type);
606         switch (src->op) {
607         case INT:
608                 if (src->op != dst->op || src->size != dst->size)
609                         p = simplify(CVI, dst, p, NULL);
610                 break;
611         case UNSIGNED:
612                 if (src->op != dst->op || src->size != dst->size)
613                         p = simplify(CVU, dst, p, NULL);
614                 break;
615         case FLOAT:
616                 if (src->op != dst->op || src->size != dst->size)
617                         p = simplify(CVF, dst, p, NULL);
618                 break;
619         case POINTER:
620                 if (src->op != dst->op)
621                         p = simplify(CVP, dst, p, NULL);
622                 else {
623                         if ((isfunc(src->type) && !isfunc(dst->type))
624                         || (!isfunc(src->type) &&  isfunc(dst->type)))
625                                 warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type);
627                         if (src->size != dst->size)
628                                 p = simplify(CVP, dst, p, NULL);
629                 }
630                 break;
631         default: assert(0);
632         }
633         return retype(p, type);
635 Tree field(Tree p, const char *name) {
636         Field q;
637         Type ty1, ty = p->type;
639         if (isptr(ty))
640                 ty = deref(ty);
641         ty1 = ty;
642         ty = unqual(ty);
643         if ((q = fieldref(name, ty)) != NULL) {
644                 if (isarray(q->type)) {
645                         ty = q->type->type;
646                         if (isconst(ty1) && !isconst(ty))
647                                 ty = qual(CONST, ty);
648                         if (isvolatile(ty1) && !isvolatile(ty))
649                                 ty = qual(VOLATILE, ty);
650                         ty = array(ty, q->type->size/ty->size, q->type->align);
651                 } else {
652                         ty = q->type;
653                         if (isconst(ty1) && !isconst(ty))
654                                 ty = qual(CONST, ty);
655                         if (isvolatile(ty1) && !isvolatile(ty))
656                                 ty = qual(VOLATILE, ty);
657                         ty = ptr(ty);
658                 }
659                 if (YYcheck && !isaddrop(p->op) && q->offset > 0)       /* omit */
660                         p = nullcall(ty, YYcheck, p, consttree(q->offset, inttype));    /* omit */
661                 else                                    /* omit */
662                 p = simplify(ADD+P, ty, p, consttree(q->offset, inttype));
664                 if (q->lsb) {
665                         p = tree(FIELD, ty->type, rvalue(p), NULL);
666                         p->u.field = q;
667                 } else if (!isarray(q->type))
668                         p = rvalue(p);
670         } else {
671                 error("unknown field `%s' of `%t'\n", name, ty);
672                 p = rvalue(retype(p, ptr(inttype)));
673         }
674         return p;
676 /* funcname - return name of function f or a function' */
677 char *funcname(Tree f) {
678         if (isaddrop(f->op))
679                 return stringf("`%s'", f->u.sym->name);
680         return "a function";
682 static Tree nullcheck(Tree p) {
683         if (!needconst && YYnull && isptr(p->type)) {
684                 p = value(p);
685                 if (strcmp(YYnull->name, "_YYnull") == 0) {
686                         Symbol t1 = temporary(REGISTER, voidptype);
687                         p = tree(RIGHT, p->type,
688                                 tree(OR, voidtype,
689                                         cond(asgn(t1, cast(p, voidptype))),
690                                         vcall(YYnull, voidtype, (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno)            , NULL)),
691                                 idtree(t1));
692                 }
694                 else
695                         p = nullcall(p->type, YYnull, p, cnsttree(inttype, 0L));
697         }
698         return p;
700 Tree nullcall(Type pty, Symbol f, Tree p, Tree e) {
701         Type ty;
703         if (isarray(pty))
704                 return retype(nullcall(atop(pty), f, p, e), pty);
705         ty = unqual(unqual(p->type)->type);
706         return vcall(f, pty,
707                 p, e,
708                 cnsttree(inttype, (long)ty->size),
709                 cnsttree(inttype, (long)ty->align),
710                 (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno)            , NULL);