mirror of
https://github.com/golang/go
synced 2024-11-20 02:34:42 -07:00
cleanup in preparation for new scoping.
walkstate -> walkstmt walktype -> walkexpr; stmts moved to walkstmt walktype and friends have a final Node **init argument that can have side effects appended, making it more explicit when they do and do not happen. this replaces the old global addtop and addtotop. delete switch map and interface conversion cases (dropped from the language months ago). R=ken OCL=31465 CL=31468
This commit is contained in:
parent
ed124a971e
commit
0dadc4fe4f
@ -17,8 +17,12 @@ dflag(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* declare (possible list) n of type t.
|
||||
* append ODCL nodes to *init
|
||||
*/
|
||||
void
|
||||
dodclvar(Node *n, Type *t)
|
||||
dodclvar(Node *n, Type *t, Node **init)
|
||||
{
|
||||
if(n == N)
|
||||
return;
|
||||
@ -26,7 +30,7 @@ dodclvar(Node *n, Type *t)
|
||||
if(t != T && (t->etype == TIDEAL || t->etype == TNIL))
|
||||
fatal("dodclvar %T", t);
|
||||
for(; n->op == OLIST; n = n->right)
|
||||
dodclvar(n->left, t);
|
||||
dodclvar(n->left, t, init);
|
||||
|
||||
dowidth(t);
|
||||
|
||||
@ -39,7 +43,7 @@ dodclvar(Node *n, Type *t)
|
||||
addvar(n, t, dclcontext);
|
||||
autoexport(n->sym);
|
||||
if(funcdepth > 0)
|
||||
addtop = list(addtop, nod(ODCL, n, N));
|
||||
*init = list(*init, nod(ODCL, n, N));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1665,13 +1669,14 @@ embedded(Sym *s)
|
||||
|
||||
/*
|
||||
* declare variables from grammar
|
||||
* new_name_list [type] = expr_list
|
||||
* new_name_list (type | [type] = expr_list)
|
||||
*/
|
||||
Node*
|
||||
variter(Node *vv, Type *t, Node *ee)
|
||||
{
|
||||
Iter viter, eiter;
|
||||
Node *v, *e, *r, *a;
|
||||
Type *tv;
|
||||
|
||||
vv = rev(vv);
|
||||
ee = rev(ee);
|
||||
@ -1680,29 +1685,31 @@ variter(Node *vv, Type *t, Node *ee)
|
||||
e = listfirst(&eiter, &ee);
|
||||
r = N;
|
||||
|
||||
loop:
|
||||
if(v == N && e == N)
|
||||
return rev(r);
|
||||
|
||||
if(v == N || e == N) {
|
||||
yyerror("shape error in var dcl");
|
||||
return rev(r);
|
||||
while(v != N) {
|
||||
if(ee != N && e == N) {
|
||||
yyerror("missing expr in var dcl");
|
||||
break;
|
||||
}
|
||||
|
||||
a = nod(OAS, v, N);
|
||||
a = N;
|
||||
if(e != N || funcdepth > 0)
|
||||
a = nod(OAS, v, e);
|
||||
tv = t;
|
||||
if(t == T) {
|
||||
gettype(e, a);
|
||||
gettype(e, &r);
|
||||
defaultlit(e, T);
|
||||
dodclvar(v, e->type);
|
||||
} else
|
||||
dodclvar(v, t);
|
||||
a->right = e;
|
||||
|
||||
tv = e->type;
|
||||
}
|
||||
dodclvar(v, tv, &r);
|
||||
r = list(r, a);
|
||||
|
||||
v = listnext(&viter);
|
||||
if(ee != N)
|
||||
e = listnext(&eiter);
|
||||
goto loop;
|
||||
}
|
||||
if(e != N)
|
||||
yyerror("extra expr in var dcl");
|
||||
return rev(r);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1713,7 +1720,7 @@ void
|
||||
constiter(Node *vv, Type *t, Node *cc)
|
||||
{
|
||||
Iter viter, citer;
|
||||
Node *v, *c, n1;
|
||||
Node *v, *c, *init;
|
||||
|
||||
if(cc == N) {
|
||||
if(t != T)
|
||||
@ -1741,9 +1748,9 @@ loop:
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&n1, 0, sizeof n1);
|
||||
gettype(c, &n1);
|
||||
if(n1.ninit != nil) {
|
||||
init = N;
|
||||
gettype(c, &init);
|
||||
if(init != N) {
|
||||
// the expression had extra code to run.
|
||||
// dodclconst is going to print an error
|
||||
// because the expression isn't constant,
|
||||
@ -1771,7 +1778,7 @@ loop:
|
||||
Node*
|
||||
unsafenmagic(Node *l, Node *r)
|
||||
{
|
||||
Node *n;
|
||||
Node *n, *init;
|
||||
Sym *s;
|
||||
Type *t, *tr;
|
||||
long v;
|
||||
@ -1787,8 +1794,9 @@ unsafenmagic(Node *l, Node *r)
|
||||
if(strcmp(s->package, "unsafe") != 0)
|
||||
goto no;
|
||||
|
||||
init = N;
|
||||
if(strcmp(s->name, "Sizeof") == 0) {
|
||||
walktype(r, Erv);
|
||||
walkexpr(r, Erv, &init);
|
||||
tr = r->type;
|
||||
if(r->op == OLITERAL && r->val.ctype == CTSTR)
|
||||
tr = types[TSTRING];
|
||||
@ -1800,12 +1808,12 @@ unsafenmagic(Node *l, Node *r)
|
||||
if(strcmp(s->name, "Offsetof") == 0) {
|
||||
if(r->op != ODOT && r->op != ODOTPTR)
|
||||
goto no;
|
||||
walktype(r, Erv);
|
||||
walkexpr(r, Erv, &init);
|
||||
v = r->xoffset;
|
||||
goto yes;
|
||||
}
|
||||
if(strcmp(s->name, "Alignof") == 0) {
|
||||
walktype(r, Erv);
|
||||
walkexpr(r, Erv, &init);
|
||||
tr = r->type;
|
||||
if(r->op == OLITERAL && r->val.ctype == CTSTR)
|
||||
tr = types[TSTRING];
|
||||
@ -1830,7 +1838,7 @@ no:
|
||||
return N;
|
||||
|
||||
yes:
|
||||
addtop = N; // any side effects disappear
|
||||
// any side effects disappear; ignore init
|
||||
val.ctype = CTINT;
|
||||
val.u.xval = mal(sizeof(*n->val.u.xval));
|
||||
mpmovecfix(val.u.xval, v);
|
||||
|
@ -601,7 +601,6 @@ EXTERN int widthptr;
|
||||
EXTERN Node* retnil;
|
||||
EXTERN Node* fskel;
|
||||
|
||||
EXTERN Node* addtop;
|
||||
EXTERN Node* typeswvar;
|
||||
|
||||
EXTERN char* structpkg;
|
||||
@ -765,7 +764,7 @@ void tempname(Node*, Type*);
|
||||
Node* staticname(Type*);
|
||||
int iscomposite(Type*);
|
||||
Node* callnew(Type*);
|
||||
Node* saferef(Node*);
|
||||
Node* saferef(Node*, Node**);
|
||||
int is64(Type*);
|
||||
int noconv(Type*, Type*);
|
||||
|
||||
@ -812,7 +811,7 @@ int simsimtype(Type*);
|
||||
/*
|
||||
* dcl.c
|
||||
*/
|
||||
void dodclvar(Node*, Type*);
|
||||
void dodclvar(Node*, Type*, Node**);
|
||||
Type* dodcltype(Type*);
|
||||
void updatetype(Type*, Type*);
|
||||
void dodclconst(Node*, Node*);
|
||||
@ -907,30 +906,29 @@ Type* pkgtype(Sym*);
|
||||
/*
|
||||
* walk.c
|
||||
*/
|
||||
void addtotop(Node*);
|
||||
void gettype(Node*, Node*);
|
||||
void gettype(Node*, Node**);
|
||||
void walk(Node*);
|
||||
void walkstate(Node*);
|
||||
void walktype(Node*, int);
|
||||
void walkconv(Node*);
|
||||
void walkstmt(Node*);
|
||||
void walkexpr(Node*, int, Node**);
|
||||
void walkconv(Node*, Node**);
|
||||
void walkas(Node*);
|
||||
void walkbool(Node*);
|
||||
void walkswitch(Node*);
|
||||
void walkselect(Node*);
|
||||
void walkdot(Node*);
|
||||
Node* ascompatee(int, Node**, Node**);
|
||||
Node* ascompatet(int, Node**, Type**, int);
|
||||
Node* ascompatte(int, Type**, Node**, int);
|
||||
void walkdot(Node*, Node**);
|
||||
Node* ascompatee(int, Node**, Node**, Node**);
|
||||
Node* ascompatet(int, Node**, Type**, int, Node**);
|
||||
Node* ascompatte(int, Type**, Node**, int, Node**);
|
||||
int ascompat(Type*, Type*);
|
||||
Node* prcompat(Node*, int);
|
||||
Node* nodpanic(int32);
|
||||
Node* newcompat(Node*);
|
||||
Node* makecompat(Node*);
|
||||
Node* stringop(Node*, int);
|
||||
Node* stringop(Node*, int, Node**);
|
||||
Type* fixmap(Type*);
|
||||
Node* mapop(Node*, int);
|
||||
Node* mapop(Node*, int, Node**);
|
||||
Type* fixchan(Type*);
|
||||
Node* chanop(Node*, int);
|
||||
Node* chanop(Node*, int, Node**);
|
||||
Node* arrayop(Node*, int);
|
||||
Node* ifacecvt(Type*, Node*, int);
|
||||
Node* ifaceop(Node*);
|
||||
@ -938,18 +936,18 @@ int ifaceas(Type*, Type*, int);
|
||||
int ifaceas1(Type*, Type*, int);
|
||||
void ifacecheck(Type*, Type*, int, int);
|
||||
void runifacechecks(void);
|
||||
Node* convas(Node*);
|
||||
Node* convas(Node*, Node**);
|
||||
void arrayconv(Type*, Node*);
|
||||
Node* colas(Node*, Node*);
|
||||
Node* colas(Node*, Node*, Node**);
|
||||
Node* dorange(Node*);
|
||||
Node* reorder1(Node*);
|
||||
Node* reorder3(Node*);
|
||||
Node* reorder4(Node*);
|
||||
Node* structlit(Node*, Node*);
|
||||
Node* arraylit(Node*, Node*);
|
||||
Node* maplit(Node*, Node*);
|
||||
Node* selectas(Node*, Node*);
|
||||
Node* old2new(Node*, Type*);
|
||||
Node* structlit(Node*, Node*, Node**);
|
||||
Node* arraylit(Node*, Node*, Node**);
|
||||
Node* maplit(Node*, Node*, Node**);
|
||||
Node* selectas(Node*, Node*, Node**);
|
||||
Node* old2new(Node*, Type*, Node**);
|
||||
void addrescapes(Node*);
|
||||
void heapmoves(void);
|
||||
|
||||
|
@ -351,30 +351,15 @@ varoptsemi:
|
||||
vardcl:
|
||||
name_list type varoptsemi
|
||||
{
|
||||
dodclvar($$, $2);
|
||||
|
||||
if(funcdepth == 0) {
|
||||
$$ = N;
|
||||
} else {
|
||||
$$ = nod(OAS, $$, N);
|
||||
addtotop($$);
|
||||
}
|
||||
$$ = variter($1, $2, N);
|
||||
}
|
||||
| name_list type varoptsemi '=' expr_list
|
||||
{
|
||||
if(addtop != N)
|
||||
fatal("new_name_list_r type '=' expr_list");
|
||||
|
||||
$$ = variter($1, $2, $5);
|
||||
addtotop($$);
|
||||
}
|
||||
| name_list '=' expr_list
|
||||
{
|
||||
if(addtop != N)
|
||||
fatal("new_name_list_r '=' expr_list");
|
||||
|
||||
$$ = variter($1, T, $3);
|
||||
addtotop($$);
|
||||
}
|
||||
|
||||
constdcl:
|
||||
@ -438,16 +423,17 @@ simple_stmt:
|
||||
}
|
||||
| expr_list LCOLAS expr_list
|
||||
{
|
||||
if(addtop != N)
|
||||
fatal("expr_list LCOLAS expr_list");
|
||||
Node *top;
|
||||
|
||||
if($3->op == OTYPESW) {
|
||||
$$ = nod(OTYPESW, $1, $3->left);
|
||||
break;
|
||||
}
|
||||
$$ = colas($$, $3);
|
||||
top = N;
|
||||
$$ = colas($$, $3, &top);
|
||||
$$ = nod(OAS, $$, $3);
|
||||
$$->colas = 1;
|
||||
addtotop($$);
|
||||
$$->ninit = top;
|
||||
}
|
||||
| expr LINC
|
||||
{
|
||||
@ -463,9 +449,12 @@ simple_stmt:
|
||||
case:
|
||||
LCASE expr_list ':'
|
||||
{
|
||||
Node *top;
|
||||
|
||||
// will be converted to OCASE
|
||||
// right will point to next case
|
||||
// done in casebody()
|
||||
top = N;
|
||||
poptodcl();
|
||||
if(typeswvar != N && typeswvar->right != N) {
|
||||
int e;
|
||||
@ -476,14 +465,14 @@ case:
|
||||
break;
|
||||
}
|
||||
if($2->op == OTYPE) {
|
||||
$$ = old2new(typeswvar->right, $2->type);
|
||||
$$ = old2new(typeswvar->right, $2->type, &top);
|
||||
$$ = nod(OTYPESW, $$, N);
|
||||
$$ = nod(OXCASE, $$, N);
|
||||
addtotop($$);
|
||||
$$->ninit = top;
|
||||
break;
|
||||
}
|
||||
e = nerrors;
|
||||
gettype($2, N);
|
||||
gettype($2, nil);
|
||||
// maybe gettype found problems that keep
|
||||
// e from being valid even outside a type switch.
|
||||
// only complain if gettype didn't print new errors.
|
||||
@ -497,15 +486,18 @@ case:
|
||||
}
|
||||
| LCASE type ':'
|
||||
{
|
||||
Node *top;
|
||||
|
||||
top = N;
|
||||
poptodcl();
|
||||
if(typeswvar == N || typeswvar->right == N) {
|
||||
yyerror("type case not in a type switch");
|
||||
$$ = N;
|
||||
} else
|
||||
$$ = old2new(typeswvar->right, $2);
|
||||
$$ = old2new(typeswvar->right, $2, &top);
|
||||
$$ = nod(OTYPESW, $$, N);
|
||||
$$ = nod(OXCASE, $$, N);
|
||||
addtotop($$);
|
||||
$$->ninit = top;
|
||||
}
|
||||
| LCASE name '=' expr ':'
|
||||
{
|
||||
@ -518,13 +510,16 @@ case:
|
||||
}
|
||||
| LCASE name LCOLAS expr ':'
|
||||
{
|
||||
Node *top;
|
||||
|
||||
// will be converted to OCASE
|
||||
// right will point to next case
|
||||
// done in casebody()
|
||||
poptodcl();
|
||||
$$ = nod(OAS, selectas($2,$4), $4);
|
||||
top = N;
|
||||
$$ = nod(OAS, selectas($2, $4, &top), $4);
|
||||
$$ = nod(OXCASE, $$, N);
|
||||
addtotop($$);
|
||||
$$->ninit = top;
|
||||
}
|
||||
| LDEFAULT ':'
|
||||
{
|
||||
@ -621,7 +616,6 @@ for_header:
|
||||
| range_stmt
|
||||
{
|
||||
$$ = dorange($1);
|
||||
addtotop($$);
|
||||
}
|
||||
|
||||
for_body:
|
||||
|
@ -249,7 +249,7 @@ mapindex(Node *n)
|
||||
b = nod(OAS, b, val);
|
||||
|
||||
a = nod(OLIST, a, b);
|
||||
walktype(a, Etop);
|
||||
walkexpr(a, Etop, nil);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
@ -517,11 +517,13 @@ appendr(Node *na, Node *nb)
|
||||
Type*
|
||||
aindex(Node *b, Type *t)
|
||||
{
|
||||
Node *top;
|
||||
Type *r;
|
||||
int bound;
|
||||
|
||||
bound = -1; // open bound
|
||||
walktype(b, Erv);
|
||||
top = N;
|
||||
walkexpr(b, Erv, &top);
|
||||
if(b != nil) {
|
||||
switch(consttype(b)) {
|
||||
default:
|
||||
@ -2452,25 +2454,26 @@ staticname(Type *t)
|
||||
}
|
||||
|
||||
/*
|
||||
* return side effect-free n, moving side effects to top.
|
||||
* return side effect-free n, appending side effects to init.
|
||||
*/
|
||||
Node*
|
||||
saferef(Node *n)
|
||||
saferef(Node *n, Node **init)
|
||||
{
|
||||
Node *l;
|
||||
Node *r;
|
||||
Node *a;
|
||||
|
||||
switch(n->op) {
|
||||
case ONAME:
|
||||
return n;
|
||||
case ODOT:
|
||||
l = saferef(n->left);
|
||||
l = saferef(n->left, init);
|
||||
if(l == n->left)
|
||||
return n;
|
||||
r = nod(OXXX, N, N);
|
||||
*r = *n;
|
||||
r->left = l;
|
||||
walktype(r, Elv);
|
||||
walkexpr(r, Elv, init);
|
||||
return r;
|
||||
|
||||
case OINDEX:
|
||||
@ -2478,9 +2481,11 @@ saferef(Node *n)
|
||||
case OIND:
|
||||
l = nod(OXXX, N, N);
|
||||
tempname(l, ptrto(n->type));
|
||||
addtop = list(addtop, nod(OAS, l, nod(OADDR, n, N)));
|
||||
a = nod(OAS, l, nod(OADDR, n, N));
|
||||
walkexpr(a, Etop, init);
|
||||
*init = list(*init, a);
|
||||
r = nod(OIND, l, N);
|
||||
walktype(r, Elv);
|
||||
walkexpr(r, Elv, init);
|
||||
return r;
|
||||
}
|
||||
fatal("saferef %N", n);
|
||||
@ -2634,11 +2639,13 @@ out:
|
||||
Node*
|
||||
adddot(Node *n)
|
||||
{
|
||||
Node *top;
|
||||
Type *t;
|
||||
Sym *s;
|
||||
int c, d;
|
||||
|
||||
walktype(n->left, Erv);
|
||||
top = N;
|
||||
walkexpr(n->left, Erv, &top);
|
||||
t = n->left->type;
|
||||
if(t == T)
|
||||
goto ret;
|
||||
@ -2666,8 +2673,8 @@ out:
|
||||
n->left->right = newname(dotlist[c].field->sym);
|
||||
}
|
||||
ret:
|
||||
n->ninit = list(addtop, n->ninit);
|
||||
addtop = N;
|
||||
if(top != N)
|
||||
n->ninit = list(top, n->ninit);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ sw0(Node *c, Type *place, int arg)
|
||||
yyerror("inappropriate case for a type switch");
|
||||
return T;
|
||||
}
|
||||
walktype(c, Erv);
|
||||
walkexpr(c, Erv, nil);
|
||||
break;
|
||||
case OTYPESW:
|
||||
if(arg != Stype)
|
||||
@ -298,7 +298,7 @@ sw3(Node *c, Type *place, int arg)
|
||||
}
|
||||
|
||||
/*
|
||||
* over all cases, call paramenter function.
|
||||
* over all cases, call parameter function.
|
||||
* four passes of these are used to allocate
|
||||
* types to cases and switch
|
||||
*/
|
||||
@ -335,7 +335,7 @@ loop:
|
||||
}
|
||||
|
||||
Node*
|
||||
newlabel()
|
||||
newlabel(void)
|
||||
{
|
||||
static int label;
|
||||
|
||||
@ -598,7 +598,7 @@ exprswitch(Node *sw)
|
||||
if(sw->ntest->val.u.bval == 0)
|
||||
arg = Sfalse;
|
||||
}
|
||||
walktype(sw->ntest, Erv);
|
||||
walkexpr(sw->ntest, Erv, &sw->ninit);
|
||||
|
||||
/*
|
||||
* pass 0,1,2,3
|
||||
@ -639,7 +639,7 @@ loop:
|
||||
if(c0 == C) {
|
||||
cas = list(cas, def);
|
||||
sw->nbody->left = rev(cas);
|
||||
walkstate(sw->nbody);
|
||||
walkstmt(sw->nbody);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -773,7 +773,7 @@ typeswitch(Node *sw)
|
||||
yyerror("type switch must have an assignment");
|
||||
return;
|
||||
}
|
||||
walktype(sw->ntest->right, Erv);
|
||||
walkexpr(sw->ntest->right, Erv, &sw->ninit);
|
||||
if(!istype(sw->ntest->right->type, TINTER)) {
|
||||
yyerror("type switch must be on an interface");
|
||||
return;
|
||||
@ -818,7 +818,7 @@ loop:
|
||||
if(c0 == C) {
|
||||
cas = list(cas, def);
|
||||
sw->nbody->left = rev(cas);
|
||||
walkstate(sw->nbody);
|
||||
walkstmt(sw->nbody);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -860,7 +860,7 @@ walkswitch(Node *sw)
|
||||
* cases have OGOTO into statements.
|
||||
* both have inserted OBREAK statements
|
||||
*/
|
||||
walkstate(sw->ninit);
|
||||
walkstmt(sw->ninit);
|
||||
if(sw->ntest == N)
|
||||
sw->ntest = nodbool(1);
|
||||
casebody(sw);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user