home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  20.5 KB  |  786 lines

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