Commit 976ca1a4 authored by Luuk van Dijk's avatar Luuk van Dijk

cmd/gc: track parameter flow, step 0: synthesize name nodes for anonymous...

cmd/gc: track parameter flow, step 0: synthesize name nodes for anonymous PPARAMOUTs without breaking anything.

further work on parameter flow tracking for escape analysis depends on this.

R=rsc
CC=golang-dev
https://golang.org/cl/6600044
parent e7f89fcb
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
void void
closurehdr(Node *ntype) closurehdr(Node *ntype)
{ {
Node *n, *name, *a; Node *n, *name, *a, *orig;
NodeList *l; NodeList *l;
n = nod(OCLOSURE, N, N); n = nod(OCLOSURE, N, N);
...@@ -43,8 +43,11 @@ closurehdr(Node *ntype) ...@@ -43,8 +43,11 @@ closurehdr(Node *ntype)
} }
for(l=n->rlist; l; l=l->next) { for(l=n->rlist; l; l=l->next) {
name = l->n->left; name = l->n->left;
if(name) if(name) {
orig = name->orig; // preserve the meaning of orig == N (anonymous PPARAMOUT)
name = newname(name->sym); name = newname(name->sym);
name->orig = orig;
}
ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, name, l->n->right)); ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, name, l->n->right));
} }
} }
......
...@@ -596,25 +596,38 @@ funcargs(Node *nt) ...@@ -596,25 +596,38 @@ funcargs(Node *nt)
} }
// declare the out arguments. // declare the out arguments.
gen = 0; gen = count(nt->list);
int i = 0;
for(l=nt->rlist; l; l=l->next) { for(l=nt->rlist; l; l=l->next) {
n = l->n; n = l->n;
if(n->op != ODCLFIELD) if(n->op != ODCLFIELD)
fatal("funcargs out %O", n->op); fatal("funcargs out %O", n->op);
if(n->left != N) {
n->left->op = ONAME; if(n->left == N) {
n->left->ntype = n->right; // give it a name so escape analysis has nodes to work with
if(isblank(n->left)) { snprint(namebuf, sizeof(namebuf), ".anon%d", gen++);
// Give it a name so we can assign to it during return. n->left = newname(lookup(namebuf));
// preserve the original in ->orig n->left->orig = N; // signal that the original was absent
nn = nod(OXXX, N, N);
*nn = *n->left; }
n->left = nn;
snprint(namebuf, sizeof(namebuf), ".anon%d", gen++); n->left->op = ONAME;
n->left->sym = lookup(namebuf);
} if(isblank(n->left)) {
declare(n->left, PPARAMOUT); // Give it a name so we can assign to it during return.
// preserve the original in ->orig
nn = nod(OXXX, N, N);
*nn = *n->left;
n->left = nn;
snprint(namebuf, sizeof(namebuf), ".anon%d", gen++);
n->left->sym = lookup(namebuf);
} }
n->left->ntype = n->right;
declare(n->left, PPARAMOUT);
n->left->vargen = i++;
} }
} }
...@@ -769,7 +782,7 @@ structfield(Node *n) ...@@ -769,7 +782,7 @@ structfield(Node *n)
break; break;
} }
if(n->left && n->left->op == ONAME) { if(n->left && n->left->op == ONAME && n->left->orig != N) {
f->nname = n->left; f->nname = n->left;
f->embedded = n->embedded; f->embedded = n->embedded;
f->sym = f->nname->sym; f->sym = f->nname->sym;
...@@ -1145,7 +1158,7 @@ functype(Node *this, NodeList *in, NodeList *out) ...@@ -1145,7 +1158,7 @@ functype(Node *this, NodeList *in, NodeList *out)
t->thistuple = 1; t->thistuple = 1;
t->outtuple = count(out); t->outtuple = count(out);
t->intuple = count(in); t->intuple = count(in);
t->outnamed = t->outtuple > 0 && out->n->left != N; t->outnamed = t->outtuple > 0 && out->n->left != N && out->n->left->orig != N;
return t; return t;
} }
......
...@@ -518,6 +518,8 @@ symfmt(Fmt *fp, Sym *s) ...@@ -518,6 +518,8 @@ symfmt(Fmt *fp, Sym *s)
return fmtprint(fp, "%s.%s", s->pkg->name, s->name); // dcommontype, typehash return fmtprint(fp, "%s.%s", s->pkg->name, s->name); // dcommontype, typehash
return fmtprint(fp, "%s.%s", s->pkg->prefix, s->name); // (methodsym), typesym, weaksym return fmtprint(fp, "%s.%s", s->pkg->prefix, s->name); // (methodsym), typesym, weaksym
case FExp: case FExp:
if(s->name && s->name[0] == '.')
fatal("exporting synthetic symbol %s", s->name);
if(s->pkg != builtinpkg) if(s->pkg != builtinpkg)
return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name); return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name);
} }
...@@ -713,9 +715,13 @@ typefmt(Fmt *fp, Type *t) ...@@ -713,9 +715,13 @@ typefmt(Fmt *fp, Type *t)
case TFIELD: case TFIELD:
if(!(fp->flags&FmtShort)) { if(!(fp->flags&FmtShort)) {
s = t->sym; s = t->sym;
// Take the name from the original, lest we substituted it with .anon%d // Take the name from the original, lest we substituted it with .anon%d
if (t->nname && (fmtmode == FErr || fmtmode == FExp)) if ((fmtmode == FErr || fmtmode == FExp) && t->nname != N)
s = t->nname->orig->sym; if(t->nname->orig != N)
s = t->nname->orig->sym;
else
s = S;
if(s != S && !t->embedded) { if(s != S && !t->embedded) {
if(fp->flags&FmtLong) if(fp->flags&FmtLong)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment