mirror of https://github.com/golang/go.git
typechecking checkpoint.
started to move typechecking to another file. can build entire tree still, but lots of work is duplicated. much to clean up. R=ken OCL=32536 CL=32543
This commit is contained in:
parent
34b277f046
commit
ff3a73b407
|
|
@ -281,7 +281,7 @@ cgen(Node *n, Node *res)
|
|||
cgen_callret(n, res);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
cgen_callret(n, res);
|
||||
break;
|
||||
|
|
@ -404,7 +404,7 @@ agen(Node *n, Node *res)
|
|||
cgen_aret(n, res);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
cgen_aret(n, res);
|
||||
break;
|
||||
|
|
@ -811,7 +811,7 @@ stkof(Node *n)
|
|||
|
||||
case OCALLMETH:
|
||||
case OCALLINTER:
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
t = n->left->type;
|
||||
if(isptr[t->etype])
|
||||
t = t->type;
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ cgen(Node *n, Node *res)
|
|||
cgen_callret(n, res);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
cgen_callret(n, res);
|
||||
break;
|
||||
|
|
@ -420,7 +420,7 @@ agen(Node *n, Node *res)
|
|||
cgen_aret(n, res);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
cgen_aret(n, res);
|
||||
break;
|
||||
|
|
@ -827,7 +827,7 @@ stkof(Node *n)
|
|||
|
||||
case OCALLMETH:
|
||||
case OCALLINTER:
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
t = n->left->type;
|
||||
if(isptr[t->etype])
|
||||
t = t->type;
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ cgen(Node *n, Node *res)
|
|||
cgen_callret(n, res);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
cgen_callret(n, res);
|
||||
break;
|
||||
|
|
@ -447,7 +447,7 @@ agen(Node *n, Node *res)
|
|||
cgen_aret(n, res);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
cgen_aret(n, res);
|
||||
break;
|
||||
|
|
@ -922,7 +922,7 @@ stkof(Node *n)
|
|||
|
||||
case OCALLMETH:
|
||||
case OCALLINTER:
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
t = n->left->type;
|
||||
if(isptr[t->etype])
|
||||
t = t->type;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ OFILES=\
|
|||
gen.$O\
|
||||
obj.$O\
|
||||
print.$O\
|
||||
typecheck.$O\
|
||||
|
||||
$(LIB): $(OFILES)
|
||||
ar rsc $(LIB) $(OFILES)
|
||||
|
|
|
|||
|
|
@ -339,6 +339,14 @@ typeinit(void)
|
|||
okfor[OCAP] = okforcap;
|
||||
okfor[OLEN] = okforlen;
|
||||
|
||||
// comparison
|
||||
iscmp[OLT] = 1;
|
||||
iscmp[OGT] = 1;
|
||||
iscmp[OGE] = 1;
|
||||
iscmp[OLE] = 1;
|
||||
iscmp[OEQ] = 1;
|
||||
iscmp[ONE] = 1;
|
||||
|
||||
mpatofix(maxintval[TINT8], "0x7f");
|
||||
mpatofix(minintval[TINT8], "-0x80");
|
||||
mpatofix(maxintval[TINT16], "0x7fff");
|
||||
|
|
|
|||
|
|
@ -89,12 +89,17 @@ convlit1(Node **np, Type *t, int explicit)
|
|||
|
||||
switch(n->op) {
|
||||
default:
|
||||
if(n->type->etype == TIDEAL) {
|
||||
convlit(&n->left, t);
|
||||
convlit(&n->right, t);
|
||||
n->type = t;
|
||||
}
|
||||
return;
|
||||
case OLITERAL:
|
||||
break;
|
||||
case OLSH:
|
||||
case ORSH:
|
||||
convlit1(&n->left, t, explicit);
|
||||
convlit(&n->left, t);
|
||||
n->type = n->left->type;
|
||||
return;
|
||||
}
|
||||
|
|
@ -259,11 +264,15 @@ overflow(Val v, Type *t)
|
|||
return;
|
||||
switch(v.ctype) {
|
||||
case CTINT:
|
||||
if(!isint[t->etype])
|
||||
fatal("overflow: %T integer constant", t);
|
||||
if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0
|
||||
|| mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0)
|
||||
yyerror("constant %B overflows %T", v.u.xval, t);
|
||||
break;
|
||||
case CTFLT:
|
||||
if(!isfloat[t->etype])
|
||||
fatal("overflow: %T floating-point constant", t);
|
||||
if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) < 0
|
||||
|| mpcmpfltflt(v.u.fval, maxfltval[t->etype]) > 0)
|
||||
yyerror("constant %#F overflows %T", v.u.fval, t);
|
||||
|
|
@ -325,6 +334,11 @@ evconst(Node *n)
|
|||
Val v;
|
||||
Mpint b;
|
||||
|
||||
switch(n->op) {
|
||||
case OMAKE:
|
||||
return;
|
||||
}
|
||||
|
||||
nl = n->left;
|
||||
if(nl == N || nl->type == T)
|
||||
return;
|
||||
|
|
@ -590,6 +604,7 @@ unary:
|
|||
case TUP(OCONV, CTINT):
|
||||
case TUP(OCONV, CTFLT):
|
||||
case TUP(OCONV, CTSTR):
|
||||
case TUP(OCONV, CTNIL):
|
||||
convlit1(&nl, n->type, 1);
|
||||
break;
|
||||
|
||||
|
|
@ -711,6 +726,11 @@ defaultlit(Node **np, Type *t)
|
|||
defaultlit(&n->left, t);
|
||||
n->type = n->left->type;
|
||||
return;
|
||||
default:
|
||||
defaultlit(&n->left, t);
|
||||
defaultlit(&n->right, t);
|
||||
n->type = n->left->type;
|
||||
return;
|
||||
}
|
||||
|
||||
lno = lineno;
|
||||
|
|
@ -753,7 +773,7 @@ defaultlit(Node **np, Type *t)
|
|||
* get the same type going out.
|
||||
*/
|
||||
void
|
||||
defaultlit2(Node **lp, Node **rp)
|
||||
defaultlit2(Node **lp, Node **rp, int force)
|
||||
{
|
||||
Node *l, *r;
|
||||
|
||||
|
|
@ -769,6 +789,8 @@ defaultlit2(Node **lp, Node **rp)
|
|||
convlit(lp, r->type);
|
||||
return;
|
||||
}
|
||||
if(!force)
|
||||
return;
|
||||
if(isconst(l, CTFLT) || isconst(r, CTFLT)) {
|
||||
convlit(lp, types[TFLOAT]);
|
||||
convlit(rp, types[TFLOAT]);
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ funclit0(Node *t)
|
|||
autodcl = dcl();
|
||||
autodcl->back = autodcl;
|
||||
|
||||
walkexpr(&t, Etype, &t->ninit);
|
||||
typecheck(&t, Etype);
|
||||
funcargs(t->type);
|
||||
return t;
|
||||
}
|
||||
|
|
@ -703,7 +703,7 @@ stotype(NodeList *l, int et, Type **t)
|
|||
if(n->op != ODCLFIELD)
|
||||
fatal("stotype: oops %N\n", n);
|
||||
if(n->right != N) {
|
||||
walkexpr(&n->right, Etype, &init);
|
||||
typecheck(&n->right, Etype);
|
||||
n->type = n->right->type;
|
||||
n->right = N;
|
||||
if(n->embedded && n->type != T) {
|
||||
|
|
@ -1298,7 +1298,7 @@ xanondcl(Node *nt)
|
|||
Node *n;
|
||||
Type *t;
|
||||
|
||||
walkexpr(&nt, Etype, &nt->ninit);
|
||||
typecheck(&nt, Etype);
|
||||
t = nt->type;
|
||||
if(nt->op != OTYPE) {
|
||||
yyerror("%S is not a type", nt->sym);
|
||||
|
|
@ -1318,7 +1318,7 @@ namedcl(Node *nn, Node *nt)
|
|||
if(nn->op == OKEY)
|
||||
nn = nn->left;
|
||||
if(nn->sym == S) {
|
||||
walkexpr(&nn, Etype, &nn->ninit);
|
||||
typecheck(&nn, Etype);
|
||||
yyerror("cannot mix anonymous %T with named arguments", nn->type);
|
||||
return xanondcl(nn);
|
||||
}
|
||||
|
|
@ -1326,7 +1326,7 @@ namedcl(Node *nn, Node *nt)
|
|||
if(nt == N)
|
||||
yyerror("missing type for argument %S", nn->sym);
|
||||
else {
|
||||
walkexpr(&nt, Etype, &nt->ninit);
|
||||
typecheck(&nt, Etype);
|
||||
if(nt->op != OTYPE)
|
||||
yyerror("%S is not a type", nt->sym);
|
||||
else
|
||||
|
|
@ -1650,7 +1650,7 @@ variter(NodeList *vl, Node *nt, NodeList *el)
|
|||
|
||||
t = T;
|
||||
if(nt) {
|
||||
walkexpr(&nt, Etype, &nt->ninit);
|
||||
typecheck(&nt, Etype);
|
||||
t = nt->type;
|
||||
}
|
||||
|
||||
|
|
@ -1763,7 +1763,7 @@ unsafenmagic(Node *fn, NodeList *args)
|
|||
|
||||
n = nod(OLITERAL, N, N);
|
||||
if(strcmp(s->name, "Sizeof") == 0) {
|
||||
walkexpr(&r, Erv, &n->ninit);
|
||||
typecheck(&r, Erv);
|
||||
tr = r->type;
|
||||
if(r->op == OLITERAL && r->val.ctype == CTSTR)
|
||||
tr = types[TSTRING];
|
||||
|
|
@ -1775,12 +1775,12 @@ unsafenmagic(Node *fn, NodeList *args)
|
|||
if(strcmp(s->name, "Offsetof") == 0) {
|
||||
if(r->op != ODOT && r->op != ODOTPTR)
|
||||
goto no;
|
||||
walkexpr(&r, Erv, &n->ninit);
|
||||
typecheck(&r, Erv);
|
||||
v = r->xoffset;
|
||||
goto yes;
|
||||
}
|
||||
if(strcmp(s->name, "Alignof") == 0) {
|
||||
walkexpr(&r, Erv, &n->ninit);
|
||||
typecheck(&r, Erv);
|
||||
tr = r->type;
|
||||
if(r->op == OLITERAL && r->val.ctype == CTSTR)
|
||||
tr = types[TSTRING];
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ gen(Node *n)
|
|||
cgen_callinter(n, N, 0);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
break;
|
||||
|
||||
|
|
@ -360,7 +360,7 @@ cgen_callmeth(Node *n, int proc)
|
|||
if(l->op != ODOTMETH)
|
||||
fatal("cgen_callmeth: not dotmethod: %N");
|
||||
|
||||
n->op = OCALL;
|
||||
n->op = OCALLFUNC;
|
||||
n->left = n->left->right;
|
||||
n->left->type = l->type;
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ cgen_proc(Node *n, int proc)
|
|||
cgen_callinter(n->left, N, proc);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
cgen_call(n->left, proc);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,14 +343,15 @@ enum
|
|||
OCONTINUE,
|
||||
OADDR,
|
||||
OIND,
|
||||
OCALL, OCALLMETH, OCALLINTER,
|
||||
OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
|
||||
OINDEX, OSLICE,
|
||||
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
|
||||
OREGISTER, OINDREG,
|
||||
OKEY, OPARAM,
|
||||
OCOMPOS, OCOMPSLICE, OCOMPMAP,
|
||||
OCONV, OCONVNOP,
|
||||
ODOTTYPE, OTYPESW,
|
||||
OCONV, OCONVNOP, OCONVRUNE, OCONVSTRB, OCONVSTRI,
|
||||
OCONVA2S,
|
||||
ODOTTYPE, OTYPESW, OTYPECASE,
|
||||
OBAD,
|
||||
|
||||
OTCHAN, OTMAP, OTSTRUCT, OTINTER, OTFUNC, OTARRAY,
|
||||
|
|
@ -440,7 +441,7 @@ enum
|
|||
Elv = 1<<2, // evaluated in lvalue context
|
||||
Erv = 1<<3, // evaluated in rvalue context
|
||||
Etype = 1<<4,
|
||||
Eideal = 1<<5,
|
||||
Ecall = 1<<5,
|
||||
};
|
||||
|
||||
#define BITS 5
|
||||
|
|
@ -593,6 +594,7 @@ EXTERN uchar okforcap[NTYPE];
|
|||
EXTERN uchar okforlen[NTYPE];
|
||||
EXTERN uchar okforarith[NTYPE];
|
||||
EXTERN uchar* okfor[OEND];
|
||||
EXTERN uchar iscmp[OEND];
|
||||
|
||||
EXTERN Mpint* minintval[NTYPE];
|
||||
EXTERN Mpint* maxintval[NTYPE];
|
||||
|
|
@ -830,7 +832,6 @@ int Wconv(Fmt*);
|
|||
int Zconv(Fmt*);
|
||||
|
||||
int lookdot0(Sym*, Type*, Type**);
|
||||
Type* lookdot1(Sym*, Type*, Type*);
|
||||
int adddot1(Sym*, Type*, int, Type**);
|
||||
Node* adddot(Node*);
|
||||
void expandmeth(Sym*, Type*);
|
||||
|
|
@ -846,7 +847,7 @@ Type* dodcltype(Type*);
|
|||
void updatetype(Type*, Type*);
|
||||
void dodclconst(Node*, Node*);
|
||||
void defaultlit(Node**, Type*);
|
||||
void defaultlit2(Node**, Node**);
|
||||
void defaultlit2(Node**, Node**, int);
|
||||
int structcount(Type*);
|
||||
void addmethod(Node*, Type*, int);
|
||||
Node* methodname(Node*, Type*);
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ typedclname:
|
|||
typedcl:
|
||||
typedclname ntype
|
||||
{
|
||||
walkexpr(&$2, Etype, &$2->ninit);
|
||||
typecheck(&$2, Etype);
|
||||
updatetype($1, $2->type);
|
||||
resumecheckwidth();
|
||||
}
|
||||
|
|
@ -478,21 +478,21 @@ case:
|
|||
yyerror("type switch case cannot be list");
|
||||
if(n->op == OLITERAL && n->val.ctype == CTNIL) {
|
||||
// case nil
|
||||
$$->list = list1(nod(OTYPESW, N, N));
|
||||
$$->list = list1(nod(OTYPECASE, N, N));
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: move
|
||||
e = nerrors;
|
||||
walkexpr(&n, Etype | Erv, &$$->ninit);
|
||||
typecheck(&n, Etype | Erv);
|
||||
if(n->op == OTYPE) {
|
||||
n = old2new(typeswvar->right, n->type, &$$->ninit);
|
||||
$$->list = list1(nod(OTYPESW, n, N));
|
||||
$$->list = list1(nod(OTYPECASE, n, N));
|
||||
break;
|
||||
}
|
||||
// maybe walkexpr found problems that keep
|
||||
// maybe typecheck found problems that keep
|
||||
// e from being valid even outside a type switch.
|
||||
// only complain if walkexpr didn't print new errors.
|
||||
// only complain if typecheck didn't print new errors.
|
||||
if(nerrors == e)
|
||||
yyerror("non-type case in type switch");
|
||||
$$->diag = 1;
|
||||
|
|
@ -518,6 +518,7 @@ case:
|
|||
// done in casebody()
|
||||
poptodcl();
|
||||
$$ = nod(OXCASE, N, N);
|
||||
typecheck(&$4, Erv);
|
||||
$$->list = list1(nod(OAS, selectas($2, $4, &$$->ninit), $4));
|
||||
}
|
||||
| LDEFAULT ':'
|
||||
|
|
@ -1143,7 +1144,7 @@ fndcl:
|
|||
n = nod(OTFUNC, N, N);
|
||||
n->list = $3;
|
||||
n->rlist = $5;
|
||||
walkexpr(&n, Etype, &n->ninit);
|
||||
typecheck(&n, Etype);
|
||||
$$->type = n->type;
|
||||
funchdr($$);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ void
|
|||
exprfmt(Fmt *f, Node *n, int prec)
|
||||
{
|
||||
int nprec;
|
||||
|
||||
|
||||
nprec = 0;
|
||||
if(n == nil) {
|
||||
fmtprint(f, "<nil>");
|
||||
|
|
@ -38,7 +38,7 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
case OLITERAL:
|
||||
nprec = 7;
|
||||
break;
|
||||
|
||||
|
||||
case OMUL:
|
||||
case ODIV:
|
||||
case OMOD:
|
||||
|
|
@ -48,14 +48,14 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
case OANDNOT:
|
||||
nprec = 6;
|
||||
break;
|
||||
|
||||
|
||||
case OADD:
|
||||
case OSUB:
|
||||
case OOR:
|
||||
case OXOR:
|
||||
nprec = 5;
|
||||
break;
|
||||
|
||||
|
||||
case OEQ:
|
||||
case OLT:
|
||||
case OLE:
|
||||
|
|
@ -64,15 +64,15 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
case ONE:
|
||||
nprec = 4;
|
||||
break;
|
||||
|
||||
|
||||
case OSEND:
|
||||
nprec = 3;
|
||||
break;
|
||||
|
||||
|
||||
case OANDAND:
|
||||
nprec = 2;
|
||||
break;
|
||||
|
||||
|
||||
case OOROR:
|
||||
nprec = 1;
|
||||
break;
|
||||
|
|
@ -117,7 +117,7 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
case ONONAME:
|
||||
fmtprint(f, "%S", n->sym);
|
||||
break;
|
||||
|
||||
|
||||
case OTYPE:
|
||||
fmtprint(f, "%T", n->type);
|
||||
break;
|
||||
|
|
@ -126,7 +126,7 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
fmtprint(f, "[]");
|
||||
exprfmt(f, n->left, PFIXME);
|
||||
break;
|
||||
|
||||
|
||||
case OTMAP:
|
||||
fmtprint(f, "map[");
|
||||
exprfmt(f, n->left, 0);
|
||||
|
|
@ -146,19 +146,31 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
exprfmt(f, n->left, PCHAN);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case OTSTRUCT:
|
||||
fmtprint(f, "<struct>");
|
||||
break;
|
||||
|
||||
|
||||
case OTINTER:
|
||||
fmtprint(f, "<inter>");
|
||||
break;
|
||||
|
||||
|
||||
case OTFUNC:
|
||||
fmtprint(f, "<func>");
|
||||
break;
|
||||
|
||||
|
||||
case OAS:
|
||||
exprfmt(f, n->left, 0);
|
||||
fmtprint(f, " = ");
|
||||
exprfmt(f, n->right, 0);
|
||||
break;
|
||||
|
||||
case OASOP:
|
||||
exprfmt(f, n->left, 0);
|
||||
fmtprint(f, " %#O= ", n->etype);
|
||||
exprfmt(f, n->right, 0);
|
||||
break;
|
||||
|
||||
case OADD:
|
||||
case OANDAND:
|
||||
case OANDNOT:
|
||||
|
|
@ -182,7 +194,7 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
fmtprint(f, " %#O ", n->op);
|
||||
exprfmt(f, n->right, nprec+1);
|
||||
break;
|
||||
|
||||
|
||||
case OADDR:
|
||||
case OCOM:
|
||||
case OIND:
|
||||
|
|
@ -195,35 +207,35 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
fmtprint(f, " ");
|
||||
exprfmt(f, n->left, 0);
|
||||
break;
|
||||
|
||||
|
||||
case OCOMPOS:
|
||||
fmtprint(f, "<compos>");
|
||||
break;
|
||||
|
||||
|
||||
case ODOT:
|
||||
case ODOTINTER:
|
||||
case ODOTMETH:
|
||||
exprfmt(f, n->left, 7);
|
||||
if(n->sym == S)
|
||||
if(n->right == N || n->right->sym == S)
|
||||
fmtprint(f, ".<nil>");
|
||||
else
|
||||
fmtprint(f, ".%s", n->sym->name);
|
||||
fmtprint(f, ".%s", n->right->sym->name);
|
||||
break;
|
||||
|
||||
|
||||
case ODOTTYPE:
|
||||
exprfmt(f, n->left, 7);
|
||||
fmtprint(f, ".(");
|
||||
exprfmt(f, n->right, 0);
|
||||
fmtprint(f, ")");
|
||||
break;
|
||||
|
||||
|
||||
case OINDEX:
|
||||
exprfmt(f, n->left, 7);
|
||||
fmtprint(f, "[");
|
||||
exprfmt(f, n->right, 0);
|
||||
fmtprint(f, "]");
|
||||
break;
|
||||
|
||||
|
||||
case OSLICE:
|
||||
exprfmt(f, n->left, 7);
|
||||
fmtprint(f, "[");
|
||||
|
|
@ -232,8 +244,9 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
exprfmt(f, n->right->right, 0);
|
||||
fmtprint(f, "]");
|
||||
break;
|
||||
|
||||
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
case OCALLINTER:
|
||||
case OCALLMETH:
|
||||
exprfmt(f, n->left, 7);
|
||||
|
|
@ -241,13 +254,13 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||
exprlistfmt(f, n->list);
|
||||
fmtprint(f, ")");
|
||||
break;
|
||||
|
||||
|
||||
case OCONV:
|
||||
fmtprint(f, "%T(", n->type);
|
||||
exprfmt(f, n->left, 0);
|
||||
fmtprint(f, ")");
|
||||
break;
|
||||
|
||||
|
||||
case OCAP:
|
||||
case OCLOSE:
|
||||
case OCLOSED:
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ aindex(Node *b, Type *t)
|
|||
|
||||
bound = -1; // open bound
|
||||
init = nil;
|
||||
walkexpr(&b, Erv, &init);
|
||||
typecheck(&b, Erv);
|
||||
if(b != nil) {
|
||||
switch(consttype(b)) {
|
||||
default:
|
||||
|
|
@ -638,6 +638,7 @@ opnames[] =
|
|||
[OBAD] = "BAD",
|
||||
[OBLOCK] = "BLOCK",
|
||||
[OBREAK] = "BREAK",
|
||||
[OCALLFUNC] = "CALLFUNC",
|
||||
[OCALLINTER] = "CALLINTER",
|
||||
[OCALLMETH] = "CALLMETH",
|
||||
[OCALL] = "CALL",
|
||||
|
|
@ -2100,6 +2101,7 @@ ullmancalc(Node *n)
|
|||
ul++;
|
||||
goto out;
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
case OCALLMETH:
|
||||
case OCALLINTER:
|
||||
ul = UINF;
|
||||
|
|
@ -2389,6 +2391,7 @@ saferef(Node *n, NodeList **init)
|
|||
r = nod(OXXX, N, N);
|
||||
*r = *n;
|
||||
r->left = l;
|
||||
typecheck(&r, Elv);
|
||||
walkexpr(&r, Elv, init);
|
||||
return r;
|
||||
|
||||
|
|
@ -2398,9 +2401,11 @@ saferef(Node *n, NodeList **init)
|
|||
l = nod(OXXX, N, N);
|
||||
tempname(l, ptrto(n->type));
|
||||
a = nod(OAS, l, nod(OADDR, n, N));
|
||||
typecheck(&a, Etop);
|
||||
walkexpr(&a, Etop, init);
|
||||
*init = list(*init, a);
|
||||
r = nod(OIND, l, N);
|
||||
typecheck(&r, Elv);
|
||||
walkexpr(&r, Elv, init);
|
||||
return r;
|
||||
}
|
||||
|
|
@ -2555,13 +2560,11 @@ out:
|
|||
Node*
|
||||
adddot(Node *n)
|
||||
{
|
||||
NodeList *init;
|
||||
Type *t;
|
||||
Sym *s;
|
||||
int c, d;
|
||||
|
||||
init = nil;
|
||||
walkexpr(&n->left, Erv, &init);
|
||||
typecheck(&n->left, Erv);
|
||||
t = n->left->type;
|
||||
if(t == T)
|
||||
goto ret;
|
||||
|
|
@ -2589,7 +2592,6 @@ out:
|
|||
n->left->right = newname(dotlist[c].field->sym);
|
||||
}
|
||||
ret:
|
||||
n->ninit = concat(init, n->ninit);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -247,14 +247,15 @@ sw0(Node **cp, Type *place, int arg)
|
|||
switch(c->op) {
|
||||
default:
|
||||
if(arg == Stype) {
|
||||
yyerror("inappropriate case for a type switch");
|
||||
yyerror("expression case in a type switch");
|
||||
return T;
|
||||
}
|
||||
walkexpr(cp, Erv, nil);
|
||||
break;
|
||||
case OTYPESW:
|
||||
case OTYPECASE:
|
||||
if(arg != Stype)
|
||||
yyerror("inappropriate type case");
|
||||
yyerror("type case in an expression switch");
|
||||
break;
|
||||
case OAS:
|
||||
yyerror("inappropriate assignment in a case statement");
|
||||
|
|
@ -542,12 +543,14 @@ exprbsw(Case *c0, int ncase, int arg)
|
|||
case Sfalse:
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(ONOT, n->left, N); // if !val
|
||||
typecheck(&a->ntest, Erv);
|
||||
a->nbody = list1(n->right); // then goto l
|
||||
break;
|
||||
|
||||
default:
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OEQ, exprname, n->left); // if name == val
|
||||
typecheck(&a->ntest, Erv);
|
||||
a->nbody = list1(n->right); // then goto l
|
||||
break;
|
||||
}
|
||||
|
|
@ -566,6 +569,7 @@ exprbsw(Case *c0, int ncase, int arg)
|
|||
c = c->link;
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OLE, exprname, c->node->left);
|
||||
typecheck(&a->ntest, Erv);
|
||||
a->nbody = list1(exprbsw(c0, half, arg));
|
||||
a->nelse = list1(exprbsw(c->link, ncase-half, arg));
|
||||
return a;
|
||||
|
|
@ -619,6 +623,7 @@ exprswitch(Node *sw)
|
|||
exprname = nod(OXXX, N, N);
|
||||
tempname(exprname, sw->ntest->type);
|
||||
cas = list1(nod(OAS, exprname, sw->ntest));
|
||||
typechecklist(cas, Etop);
|
||||
}
|
||||
|
||||
c0 = mkcaselist(sw, arg);
|
||||
|
|
@ -686,6 +691,7 @@ typeone(Node *t)
|
|||
b = nod(ODOTTYPE, facename, N);
|
||||
b->type = t->left->left->type; // interface.(type)
|
||||
a->rlist = list1(b);
|
||||
typecheck(&a, Etop);
|
||||
init = list(init, a);
|
||||
|
||||
b = nod(OIF, N, N);
|
||||
|
|
@ -716,6 +722,7 @@ typebsw(Case *c0, int ncase)
|
|||
v.ctype = CTNIL;
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OEQ, facename, nodlit(v));
|
||||
typecheck(&a->ntest, Erv);
|
||||
a->nbody = list1(n->right); // if i==nil { goto l }
|
||||
cas = list(cas, a);
|
||||
break;
|
||||
|
|
@ -728,6 +735,7 @@ typebsw(Case *c0, int ncase)
|
|||
case Ttypeconst:
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
|
||||
typecheck(&a->ntest, Erv);
|
||||
a->nbody = list1(typeone(n));
|
||||
cas = list(cas, a);
|
||||
break;
|
||||
|
|
@ -744,6 +752,7 @@ typebsw(Case *c0, int ncase)
|
|||
c = c->link;
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OLE, hashname, nodintconst(c->hash));
|
||||
typecheck(&a->ntest, Erv);
|
||||
a->nbody = list1(typebsw(c0, half));
|
||||
a->nelse = list1(typebsw(c->link, ncase-half));
|
||||
return a;
|
||||
|
|
@ -786,13 +795,16 @@ typeswitch(Node *sw)
|
|||
facename = nod(OXXX, N, N);
|
||||
tempname(facename, sw->ntest->right->type);
|
||||
a = nod(OAS, facename, sw->ntest->right);
|
||||
typecheck(&a, Etop);
|
||||
cas = list(cas, a);
|
||||
|
||||
boolname = nod(OXXX, N, N);
|
||||
tempname(boolname, types[TBOOL]);
|
||||
typecheck(&boolname, Erv);
|
||||
|
||||
hashname = nod(OXXX, N, N);
|
||||
tempname(hashname, types[TUINT32]);
|
||||
typecheck(&hashname, Erv);
|
||||
|
||||
t = sw->ntest->right->type;
|
||||
if(isnilinter(t))
|
||||
|
|
@ -803,6 +815,7 @@ typeswitch(Node *sw)
|
|||
a = nod(OCALL, a, N);
|
||||
a->list = list1(facename);
|
||||
a = nod(OAS, hashname, a);
|
||||
typecheck(&a, Etop);
|
||||
cas = list(cas, a);
|
||||
|
||||
c0 = mkcaselist(sw, Stype);
|
||||
|
|
@ -861,8 +874,10 @@ walkswitch(Node *sw)
|
|||
* both have inserted OBREAK statements
|
||||
*/
|
||||
walkstmtlist(sw->ninit);
|
||||
if(sw->ntest == N)
|
||||
if(sw->ntest == N) {
|
||||
sw->ntest = nodbool(1);
|
||||
typecheck(&sw->ntest, Erv);
|
||||
}
|
||||
casebody(sw);
|
||||
|
||||
if(sw->ntest->op == OTYPESW) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue