1#include <assert.h>2#include <stdlib.h>3#include <string.h>45#include <scc/cstd.h>6#include <scc/scc.h>7#include "cc1.h"89#define XCHG(lp, rp, np) (np = lp, lp = rp, rp = np)1011int12power2node(Node *np, int *log)13{14 int n;15 unsigned long long u;16 Symbol *sym;1718 if (!np || !(np->flags & NCONST) || !np->sym)19 return 0;2021 sym = np->sym;22 if (sym->type->op != INT || (u = sym->u.u) == 0)23 return 0;2425 for (n = 0; (u & 1) == 0; n++)26 u >>= 1;2728 if (log)29 *log = n;3031 return u == 1;32}3334int35cmpnode(Node *np, unsigned long long val)36{37 Symbol *sym;38 Type *tp;39 unsigned long long mask, nodeval;4041 if (!np || !(np->flags & NCONST) || !np->sym)42 return 0;43 sym = np->sym;44 tp = sym->type;4546 switch (tp->op) {47 case ENUM:48 case PTR:49 case INT:50 mask = (val > 1) ? ones(np->type->size) : -1;51 nodeval = (tp->prop & TSIGNED) ? sym->u.i : sym->u.u;52 return (nodeval & mask) == (val & mask);53 case FLOAT:54 if (tp == floattype)55 return sym->u.f == val;56 else if (tp == doubletype)57 return sym->u.d == val;58 else59 return sym->u.d == val;60 break;61 default:62 abort();63 }64 return 0;65}6667static Node *68promote(Node *np)69{70 Type *tp;71 Node *new;72 struct limits *lim, *ilim;7374 tp = np->type;7576 switch (tp->op) {77 case ENUM:78 case INT:79 if (tp->n.rank >= inttype->n.rank)80 return np;81 lim = getlimits(tp);82 ilim = getlimits(inttype);83 tp = (lim->max.i <= ilim->max.i) ? inttype : uinttype;84 break;85 case FLOAT:86 return np;87 default:88 abort();89 }90 if ((new = convert(np, tp, 1)) != NULL)91 return new;92 return np;93}9495static void96arithconv(Node **p1, Node **p2)97{98 int to = 0, s1, s2;99 unsigned r1, r2;100 Type *tp1, *tp2;101 Node *np1, *np2;102 struct limits *lp1, *lp2;103104 np1 = promote(*p1);105 np2 = promote(*p2);106107 tp1 = np1->type;108 tp2 = np2->type;109110 if (tp1 == tp2)111 goto set_p1_p2;112113 s1 = (tp1->prop & TSIGNED) != 0;114 r1 = tp1->n.rank;115 lp1 = getlimits(tp1);116117 s2 = (tp2->prop & TSIGNED) != 0;118 r2 = tp2->n.rank;119 lp2 = getlimits(tp2);120121 if (s1 == s2 || tp1->op == FLOAT || tp2->op == FLOAT) {122 to = r1 - r2;123 } else if (!s1) {124 if (r1 >= r2 || lp1->max.i >= lp2->max.i)125 to = 1;126 else127 to = -1;128 } else {129 if (r2 >= r1 || lp2->max.i >= lp1->max.i)130 to = -1;131 else132 to = 1;133 }134135 if (to > 0)136 np2 = convert(np2, tp1, 1);137 else if (to < 0)138 np1 = convert(np1, tp2, 1);139140set_p1_p2:141 *p1 = np1;142 *p2 = np2;143}144145static int146null(Node *np)147{148 if (np->type != pvoidtype)149 return 0;150151 switch (np->op) {152 case OCAST:153 np = np->left;154 if (np->type != inttype)155 return 0;156 case OSYM:157 return cmpnode(np, 0);158 default:159 return 0;160 }161}162163static Node *164chkternary(Node *yes, Node *no)165{166 /*167 * FIXME:168 * We are ignoring type qualifiers here,169 * but the standard has strong rules about this.170 * take a look to 6.5.15171 */172173 if (!eqtype(yes->type, no->type, EQUIV)) {174 if ((yes->type->prop & TARITH) && (no->type->prop & TARITH)) {175 arithconv(&yes, &no);176 } else if (yes->type->op != PTR && no->type->op != PTR) {177 goto wrong_type;178 } else {179 /* convert integer 0 to NULL */180 if ((yes->type->prop & TINTEGER) && cmpnode(yes, 0))181 yes = convert(yes, pvoidtype, 0);182 if ((no->type->prop & TINTEGER) && cmpnode(no, 0))183 no = convert(no, pvoidtype, 0);184 /*185 * At this point the type of both should be186 * a pointer to something, or we have don't187 * compatible types188 */189 if (yes->type->op != PTR || no->type->op != PTR)190 goto wrong_type;191 /*192 * If we have a null pointer constant then193 * convert to the another type194 */195 if (null(yes))196 yes = convert(yes, no->type, 0);197 if (null(no))198 no = convert(no, yes->type, 0);199200 if (!eqtype(yes->type, no->type, EQUIV))201 goto wrong_type;202 }203 }204 return node(OCOLON, yes->type, yes, no);205206wrong_type:207 errorp("type mismatch in conditional expression");208 freetree(yes);209 freetree(no);210 return constnode(zero);211}212213static void214chklvalue(Node *np)215{216 if (!(np->flags & NLVAL))217 errorp("lvalue required in operation");218 if (np->type == voidtype)219 errorp("invalid use of void expression");220}221222static Node *223chkconstaddr(Node *var, Node *addr)224{225 unsigned mask = SGLOBAL|SLOCAL|SPRIVATE|SEXTERN;226227 if (var->sym && var->sym->flags & mask228 || var->op == OFIELD && var->left->op == OSYM229 || var->op == OFIELD && (var->left->flags & NCONST)) {230 addr->flags |= NCONST;231 }232233 return addr;234}235236Node *237decay(Node *np)238{239 Node *new;240 Type *tp = np->type;241242 switch (tp->op) {243 case ARY:244 DBG("EXPR decay ary");245 tp = tp->type;246 if (np->op != OPTR)247 goto new_node;248 new = np->left;249 free(np);250 new->type = mktype(tp, PTR, 0, NULL);251 return chkconstaddr(new, new);252 case FTN:253 DBG("EXPR decay function");254 new_node:255 new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL);256 new->flags |= NDECAY;257 return chkconstaddr(np, new);258 default:259 return np;260 }261}262263static Node *264integerop(int op, Node *lp, Node *rp)265{266 if (!(lp->type->prop & TINTEGER) || !(rp->type->prop & TINTEGER))267 error("operator requires integer operands");268269270 switch (op) {271 case OA_MOD:272 case OA_SHL:273 case OA_SHR:274 case OA_AND:275 case OA_XOR:276 case OA_OR:277 rp = convert(rp, lp->type, 0);278 break;279 default:280 arithconv(&lp, &rp);281 break;282 }283284 return node(op, lp->type, lp, rp);285}286287static Node *288integeruop(int op, Node *np)289{290 if (!(np->type->prop & TINTEGER))291 error("unary operator requires integer operand");292 np = promote(np);293 return node(op, np->type, np, NULL);294}295296static Node *297numericaluop(int op, Node *np)298{299 if (!(np->type->prop & TARITH))300 error("unary operator requires numerical operand");301 np = promote(np);302 return node(op, np->type, np, NULL);303}304305Node *306convert(Node *np, Type *newtp, int iscast)307{308 Type *oldtp = np->type;309 int op = newtp->op;310311 if (eqtype(newtp, oldtp, EQUAL))312 return np;313 if (iscast && op == VOID)314 goto good_conv;315316 switch (oldtp->op) {317 case ENUM:318 case INT:319 if (op == PTR && (iscast || cmpnode(np, 0)))320 goto good_conv;321 case FLOAT:322 if (op == INT || op == FLOAT || op == ENUM)323 goto good_conv;324 return NULL;325 case PTR:326 if (op == ENUM || op == INT) {327 if (iscast)328 goto good_conv;329 } else if (op == PTR) {330 if (eqtype(newtp, oldtp, EQUIV))331 goto good_ptr_conv;332 if (iscast)333 goto good_ptr_conv;334 if (newtp == pvoidtype || oldtp == pvoidtype)335 goto good_ptr_conv;336 }337 default:338 return NULL;339 }340341good_ptr_conv:342 np->type = newtp;343 return np;344345good_conv:346 return node(OCAST, newtp, np, NULL);347}348349static Node *350parithmetic(int op, Node *lp, Node *rp)351{352 Type *tp;353 Node *size, *np;354355 if (lp->type->op != PTR)356 XCHG(lp, rp, np);357358 tp = rp->type;359 if (tp->op == PTR && !(tp->type->prop & TDEFINED))360 goto incomplete;361 tp = lp->type;362 if (!(tp->type->prop & TDEFINED))363 goto incomplete;364 size = sizeofnode(tp->type);365366 if (op == OSUB && rp->type->op == PTR) {367 if ((rp = convert(rp, lp->type, 0)) == NULL)368 goto incorrect;369 lp = node(OSUB, pdifftype, lp, rp);370 return node(ODIV, pdifftype, lp, size);371 }372 if (!(rp->type->prop & TINTEGER))373 goto incorrect;374375 rp = convert(promote(rp), sizettype, 0);376 rp = node(OMUL, sizettype, rp, size);377 rp = convert(rp, tp, 1);378379 return node(op, tp, lp, rp);380381incomplete:382 errorp("invalid use of undefined type");383 return lp;384incorrect:385 errorp("incorrect arithmetic operands");386 return lp;387388}389390static Node *391arithmetic(int op, Node *lp, Node *rp)392{393 Node *np;394 Type *ltp = lp->type, *rtp = rp->type;395396 if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) {397 switch (op) {398 case OA_ADD:399 case OA_SUB:400 case OA_MUL:401 case OA_DIV:402 rp = convert(rp, lp->type, 0);403 break;404 default:405 arithconv(&lp, &rp);406 break;407 }408 return node(op, lp->type, lp, rp);409 } else if ((ltp->op == PTR || rtp->op == PTR)) {410 switch (op) {411 case OADD:412 case OSUB:413 case OA_ADD:414 case OA_SUB:415 case OINC:416 case ODEC:417 np = parithmetic(op, lp, rp);418 if ((lp->flags&NCONST) && (rp->flags&NCONST))419 np->flags |= NCONST;420 return np;421 }422 }423 errorp("incorrect arithmetic operands");424 return lp;425}426427static Node *428pcompare(int op, Node *lp, Node *rp)429{430 Node *np;431432 if (lp->type->prop&TINTEGER) {433 if ((np = convert(lp, rp->type, 0)) == NULL)434 errorp("incompatible types in comparison");435 else436 lp = np;437 }438 if (rp->type->prop&TINTEGER) {439 if ((np = convert(rp, lp->type, 0)) == NULL)440 errorp("incompatible types in comparison");441 else442 rp = np;443 }444445 return convert(node(op, pvoidtype, lp, rp), inttype, 1);446}447448static Node *449compare(int op, Node *lp, Node *rp)450{451 Type *ltp, *rtp;452453 ltp = lp->type;454 rtp = rp->type;455456 if (ltp->op == PTR || rtp->op == PTR) {457 return pcompare(op, lp, rp);458 } else if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) {459 arithconv(&lp, &rp);460 return convert(node(op, lp->type, lp, rp), inttype, 1);461 } else {462 errorp("incompatible types in comparison");463 freetree(lp);464 freetree(rp);465 return constnode(zero);466 }467}468469int470negop(int op)471{472 switch (op) {473 case OEQ: return ONE;474 case ONE: return OEQ;475 case OLT: return OGE;476 case OGE: return OLT;477 case OLE: return OGT;478 case OGT: return OLE;479 default: abort();480 }481 return op;482}483484static Node *485exp2cond(Node *np, int neg)486{487 int op;488489 if (np->type->prop & TAGGREG) {490 errorp("used struct/union type value where scalar is required");491 return constnode(zero);492 }493 switch (np->op) {494 case ONEG:495 case OOR:496 case OAND:497 return (neg) ? node(ONEG, inttype, np, NULL) : np;498 case OEQ:499 case ONE:500 case OLT:501 case OGE:502 case OLE:503 case OGT:504 if (neg)505 np->op = negop(np->op);506 return np;507 default:508 op = (neg) ? OEQ : ONE;509 return compare(op, np, constnode(zero));510 }511}512513static Node *514logic(int op, Node *lp, Node *rp)515{516 lp = exp2cond(lp, 0);517 rp = exp2cond(rp, 0);518 return node(op, inttype, lp, rp);519}520521static Node *522field(Node *np)523{524 Symbol *sym;525526 namespace = np->type->ns;527 next();528 namespace = NS_IDEN;529530 sym = yylval.sym;531 if (yytoken != IDEN)532 unexpected();533 next();534535 if (!(np->type->prop & TAGGREG)) {536 errorp("request for member '%s' in something not a structure or union",537 yylval.sym->name);538 goto free_np;539 }540 if ((sym->flags & SDECLARED) == 0) {541 errorp("incorrect field in struct/union");542 goto free_np;543 }544 np = node(OFIELD, sym->type, np, varnode(sym));545 np->flags |= NLVAL;546 return np;547548free_np:549 freetree(np);550 return constnode(zero);551}552553static Node *554content(int op, Node *np)555{556 if (np->type->op != PTR) {557 errorp("invalid argument of memory indirection");558 } else {559 np = node(op, np->type->type, np, NULL);560 np->flags |= NLVAL;561 }562 return np;563}564565static Node *566array(Node *lp, Node *rp)567{568 Type *tp;569 Node *np;570571 if (!(lp->type->prop & TINTEGER) && !(rp->type->prop & TINTEGER))572 error("array subscript is not an integer");573 np = arithmetic(OADD, lp, rp);574 tp = np->type;575 if (tp->op != PTR)576 errorp("subscripted value is neither array nor pointer");577 return content(OPTR, np);578}579580static Node *581assignop(int op, Node *lp, Node *rp)582{583 if ((rp = convert(rp, lp->type, 0)) == NULL) {584 errorp("incompatible types when assigning");585 return lp;586 }587588 return node(op, lp->type, lp, rp);589}590591static Node *592incdec(Node *np, int op)593{594 Type *tp = np->type;595 Node *inc;596597 chklvalue(np);598 np->flags |= NEFFECT;599600 if (!(tp->prop & TDEFINED)) {601 errorp("invalid use of undefined type");602 return np;603 } else if (tp->op == PTR && !(tp->type->prop & TDEFINED)) {604 errorp("%s of pointer to an incomplete type",605 (op == OINC || op == OA_ADD) ? "increment" : "decrement");606 return np;607 } else if (tp->op == PTR || (tp->prop & TARITH)) {608 inc = constnode(one);609 } else {610 errorp("wrong type argument to increment or decrement");611 return np;612 }613 return arithmetic(op, np, inc);614}615616static Node *617address(int op, Node *np)618{619 Node *new;620 Type *tp;621 Symbol *sym = np->sym;622623 if ((np->flags & NDECAY) != 0) {624 new = np->left;625 free(np);626 np = new;627 }628 tp = np->type;629630 /*631 * ansi c accepts & applied to a function name, and it generates632 * a function pointer633 */634 if (np->op == OSYM) {635 if (tp->op == FTN)636 return decay(np);637 if (tp->op == ARY)638 goto dont_check_lvalue;639 }640 chklvalue(np);641642dont_check_lvalue:643 if (sym && (sym->flags & SREGISTER))644 errorp("address of register variable '%s' requested", yytext);645 new = node(op, mktype(tp, PTR, 0, NULL), np, NULL);646647 return chkconstaddr(np, new);648}649650static Node *651negation(int op, Node *np)652{653 if (!(np->type->prop & TARITH) && np->type->op != PTR) {654 errorp("invalid argument of unary '!'");655 return constnode(zero);656 }657 return exp2cond(np, 1);658}659660static Symbol *661adjstrings(Symbol *sym)662{663 char *d, *s;664 Type *tp, *base;665 size_t len, n, osiz, nsiz;666667 tp = sym->type;668 base = tp->type;669 for (len = tp->n.elem; next() == STRING; len += n - 1) {670 if (yylval.sym->type->type != base)671 break;672673 d = sym->u.s;674 s = yylval.sym->u.s;675 n = yylval.sym->type->n.elem;676 osiz = (len-1) * base->size;677 nsiz = n * base->size;678679 sym->u.s = d = xrealloc(d, osiz + nsiz);680 memcpy(d + osiz, s, nsiz);681 }682683 if (tp->n.elem != len)684 sym->type = mktype(base, ARY, len, NULL);685686 return sym;687}688689static Node *690funcsym(Symbol *sym)691{692 char *s;693 Node *np;694695 sym = install(sym->ns, sym);696 s = curfun->name;697 np = constnode(newstring(s, strlen(s)+1));698 sym->type = np->type;699 sym->flags |= SHASINIT | SLOCAL | SUSED;700 emit(ODECL, sym);701 emit(OINIT, np);702703 return varnode(sym);704}705706/*************************************************************707 * grammar functions *708 *************************************************************/709static Node *710primary(void)711{712 Node *np;713 Symbol *sym;714 Node *(*fun)(Symbol *);715716 sym = yylval.sym;717 switch (yytoken) {718 case STRING:719 adjstrings(sym);720 sym->flags |= SHASINIT;721 if (!disstring) {722 emit(ODECL, sym);723 emit(OINIT, constnode(sym));724 }725 return varnode(sym);726 case BUILTIN:727 fun = sym->u.fun;728 next();729 expect('(');730 np = (*fun)(sym);731 expect(')');732733 /* do not call to next */734 return np;735 case CONSTANT:736 np = constnode(sym);737 break;738 case DEFINED:739 np = defined();740 break;741 case '(':742 next();743 np = expr();744 expect(')');745746 /* do not call to next */747 return np;748 case IDEN:749 assert((sym->flags & SCONSTANT) == 0);750 if ((sym->flags & SDECLARED) != 0) {751 sym->flags |= SUSED;752 np = varnode(sym);753 } else if (namespace == NS_CPP) {754 np = constnode(zero);755 } else if (!strcmp(yytext, "__func__") && curctx > PARAMCTX) {756 np = funcsym(sym);757 } else {758 errorp("'%s' undeclared", yytext);759 sym->type = inttype;760 sym = install(sym->ns, sym);761 sym->flags |= SUSED;762 np = varnode(sym);763 }764 break;765 default:766 unexpected();767 }768 next();769770 return np;771}772773static Node *774arguments(Node *np)775{776 int toomany, n, op;777 Node *par = NULL, *arg;778 Type *argtype, *tp = np->type, *rettype;779 Type **targs = (Type *[]) {ellipsistype};780781 if (tp->op == PTR && tp->type->op == FTN) {782 np = content(OPTR, np);783 tp = np->type;784 }785 if (tp->op != FTN) {786 n = 1;787 rettype = inttype;788 errorp("function or function pointer expected");789 } else {790 targs = tp->p.pars;791 n = tp->n.elem;792 rettype = tp->type;793 }794795 expect('(');796 if (yytoken == ')')797 goto no_pars;798 toomany = 0;799800 do {801 arg = assign();802 argtype = *targs;803 if (argtype == ellipsistype) {804 n = 0;805 switch (arg->type->op) {806 case INT:807 arg = promote(arg);808 break;809 case FLOAT:810 if (arg->type == floattype)811 arg = convert(arg, doubletype, 1);812 break;813 }814 par = node(OPAR, arg->type, par, arg);815 continue;816 }817 if (--n < 0) {818 if (!toomany)819 errorp("too many arguments in function call");820 toomany = 1;821 continue;822 }823 ++targs;824 if ((arg = convert(arg, argtype, 0)) != NULL) {825 par = node(OPAR, arg->type, par, arg);826 continue;827 }828 errorp("incompatible type for argument %d in function call",829 tp->n.elem - n);830 } while (accept(','));831832no_pars:833 expect(')');834 if (n > 0 && *targs != ellipsistype)835 errorp("too few arguments in function call");836837 op = (tp->prop&TELLIPSIS) ? OCALLE : OCALL;838 return node(op, rettype, np, par);839}840841static Type *842gettype(Node *np)843{844 Node *new;845 Type *tp;846847 if (np == NULL)848 unexpected();849 if ((np->flags & NDECAY) != 0) {850 new = np->left;851 free(np);852 np = new;853 }854 tp = np->type;855 freetree(np);856 return tp;857}858859static Node *unary(void);860861static Node *862postfix(Node *lp)863{864 int op;865 Node *rp;866867 for (;;) {868 switch (yytoken) {869 case '[':870 next();871 rp = expr();872 expect(']');873 lp = array(decay(lp), rp);874 break;875 case DEC:876 case INC:877 op = (yytoken == INC) ? OINC : ODEC;878 lp = incdec(decay(lp), op);879 next();880 break;881882 case INDIR:883 lp = content(OPTR, decay(lp));884 case '.':885 lp = field(decay(lp));886 break;887 case '(':888 lp = arguments(decay(lp));889 lp->flags |= NEFFECT;890 break;891 default:892 return lp;893 }894 }895}896897static Type *898sizeexp(void)899{900 Node *np;901 Type *tp;902903 if (!accept('('))904 return gettype(unary());905906 switch (yytoken) {907 case TYPE:908 case TYPEIDEN:909 tp = typename();910 expect(')');911 break;912 default:913 np = expr();914 expect(')');915 tp = gettype(postfix(np));916 break;917 }918919 return tp;920}921922static Node *cast(void);923924static Node *925unary(void)926{927 Node *(*fun)(int, Node *), *np;928 int op;929 Type *tp;930931 switch (yytoken) {932 case '!': op = 0; fun = negation; break;933 case '+': op = OADD; fun = numericaluop; break;934 case '-': op = OSNEG; fun = numericaluop; break;935 case '~': op = OCPL; fun = integeruop; break;936 case '&': op = OADDR; fun = address; break;937 case '*': op = OPTR; fun = content; break;938 case SIZEOF:939 disstring = 1;940 next();941 tp = sizeexp();942 disstring = 0;943 if (!(tp->prop & TDEFINED))944 errorp("sizeof applied to an incomplete type");945 return sizeofnode(tp);946 case INC:947 case DEC:948 op = (yytoken == INC) ? OA_ADD : OA_SUB;949 next();950 np = incdec(unary(), op);951 goto decay;952 case DEFINED:953 return defined();954 default:955 np = postfix(primary());956 goto decay;957 }958959 next();960 np = (*fun)(op, cast());961962decay:963 return decay(np);964}965966static Node *967cast(void)968{969 Node *tmp, *np;970 Type *tp;971 static int nested;972973 if (!accept('('))974 return unary();975976 switch (yytoken) {977 case TQUALIFIER:978 case TYPE:979 case TYPEIDEN:980 tp = typename();981 expect(')');982983 if (yytoken == '{') {984 Symbol *sym = newsym(NS_IDEN, NULL);985 sym->id = newid();986 sym->type = tp;987 sym->flags |= (curctx == GLOBALCTX) ? SPRIVATE : SAUTO;988 initializer(sym);989990 return decay(varnode(sym));991 }992993 switch (tp->op) {994 case ARY:995 error("cast specifies an array type");996 default:997 tmp = cast();998 if ((np = convert(tmp, tp, 1)) == NULL)999 error("bad type conversion requested");1000 np->flags &= ~NLVAL;1001 }1002 break;1003 default:1004 if (nested == NR_SUBEXPR)1005 error("too many expressions nested by parentheses");1006 ++nested;1007 np = expr();1008 --nested;1009 expect(')');1010 np = postfix(np);1011 break;1012 }10131014 return np;1015}10161017static Node *1018mul(void)1019{1020 Node *np, *(*fun)(int, Node *, Node *);1021 int op;10221023 np = cast();1024 for (;;) {1025 switch (yytoken) {1026 case '*': op = OMUL; fun = arithmetic; break;1027 case '/': op = ODIV; fun = arithmetic; break;1028 case '%': op = OMOD; fun = integerop; break;1029 default: return np;1030 }1031 next();1032 np = (*fun)(op, np, cast());1033 }1034}10351036static Node *1037add(void)1038{1039 int op;1040 Node *np;10411042 np = mul();1043 for (;;) {1044 switch (yytoken) {1045 case '+': op = OADD; break;1046 case '-': op = OSUB; break;1047 default: return np;1048 }1049 next();1050 np = arithmetic(op, np, mul());1051 }1052}10531054static Node *1055shift(void)1056{1057 int op;1058 Node *np;10591060 np = add();1061 for (;;) {1062 switch (yytoken) {1063 case SHL: op = OSHL; break;1064 case SHR: op = OSHR; break;1065 default: return np;1066 }1067 next();1068 np = integerop(op, np, add());1069 }1070}10711072static Node *1073relational(void)1074{1075 int op;1076 Node *np;10771078 np = shift();1079 for (;;) {1080 switch (yytoken) {1081 case '<': op = OLT; break;1082 case '>': op = OGT; break;1083 case GE: op = OGE; break;1084 case LE: op = OLE; break;1085 default: return np;1086 }1087 next();1088 np = compare(op, np, shift());1089 }1090}10911092static Node *1093eq(void)1094{1095 int op;1096 Node *np;10971098 np = relational();1099 for (;;) {1100 switch (yytoken) {1101 case EQ: op = OEQ; break;1102 case NE: op = ONE; break;1103 default: return np;1104 }1105 next();1106 np = compare(op, np, relational());1107 }1108}11091110static Node *1111bit_and(void)1112{1113 Node *np;11141115 np = eq();1116 while (accept('&'))1117 np = integerop(OBAND, np, eq());1118 return np;1119}11201121static Node *1122bit_xor(void)1123{1124 Node *np;11251126 np = bit_and();1127 while (accept('^'))1128 np = integerop(OBXOR, np, bit_and());1129 return np;1130}11311132static Node *1133bit_or(void)1134{1135 Node *np;11361137 np = bit_xor();1138 while (accept('|'))1139 np = integerop(OBOR, np, bit_xor());1140 return np;1141}11421143static Node *1144and(void)1145{1146 Node *np;11471148 np = bit_or();1149 while (accept(AND))1150 np = logic(OAND, np, bit_or());1151 return np;1152}11531154static Node *1155or(void)1156{1157 Node *np;11581159 np = and();1160 while (accept(OR))1161 np = logic(OOR, np, and());1162 return np;1163}11641165static Node *1166ternary(void)1167{1168 Node *cond;11691170 cond = or();1171 while (accept('?')) {1172 Node *ifyes, *ifno, *np;11731174 cond = exp2cond(cond, 0);1175 ifyes = expr();1176 expect(':');1177 ifno = ternary();1178 np = chkternary(ifyes, ifno);1179 cond = node(OASK, np->type, cond, np);1180 }1181 return cond;1182}11831184Node *1185assign(void)1186{1187 Node *np, *(*fun)(int , Node *, Node *);1188 int op;11891190 np = ternary();1191 for (;;) {1192 switch (yytoken) {1193 case '=': op = OASSIGN; fun = assignop; break;1194 case MUL_EQ: op = OA_MUL; fun = arithmetic; break;1195 case DIV_EQ: op = OA_DIV; fun = arithmetic; break;1196 case MOD_EQ: op = OA_MOD; fun = integerop; break;1197 case ADD_EQ: op = OA_ADD; fun = arithmetic; break;1198 case SUB_EQ: op = OA_SUB; fun = arithmetic; break;1199 case SHL_EQ: op = OA_SHL; fun = integerop; break;1200 case SHR_EQ: op = OA_SHR; fun = integerop; break;1201 case AND_EQ: op = OA_AND; fun = integerop; break;1202 case XOR_EQ: op = OA_XOR; fun = integerop; break;1203 case OR_EQ: op = OA_OR; fun = integerop; break;1204 default: return np;1205 }1206 chklvalue(np);1207 np->flags |= NEFFECT;1208 next();1209 np = (fun)(op, np, assign());1210 }1211}12121213Node *1214expr(void)1215{1216 Node *lp, *rp;12171218 lp = assign();1219 while (accept(',')) {1220 rp = assign();1221 lp = node(OCOMMA, rp->type, lp, rp);1222 }12231224 return lp;1225}12261227Node *1228iconstexpr(void)1229{1230 Node *np;12311232 np = ternary();1233 if (np && np->type->op == INT) {1234 np = simplify(convert(np, inttype, 0));1235 if (np->flags & NCONST)1236 return np;1237 }1238 freetree(np);1239 return NULL;1240}12411242Node *1243condexpr(int neg)1244{1245 Node *np;12461247 np = exp2cond(expr(), neg);1248 if (np->flags & NCONST)1249 warn("conditional expression is constant");1250 return simplify(np);1251}