summaryrefslogtreecommitdiff
path: root/src/cmd/gc/fmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/fmt.c')
-rw-r--r--src/cmd/gc/fmt.c127
1 files changed, 95 insertions, 32 deletions
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
index 5672c0010..ab81e6c88 100644
--- a/src/cmd/gc/fmt.c
+++ b/src/cmd/gc/fmt.c
@@ -228,6 +228,7 @@ goopnames[] =
[ORANGE] = "range",
[OREAL] = "real",
[ORECV] = "<-",
+ [ORECOVER] = "recover",
[ORETURN] = "return",
[ORSH] = ">>",
[OSELECT] = "select",
@@ -289,7 +290,7 @@ Jconv(Fmt *fp)
fmtprint(fp, " l(%d)", n->lineno);
if(!c && n->xoffset != BADWIDTH)
- fmtprint(fp, " x(%lld%+d)", n->xoffset, n->stkdelta);
+ fmtprint(fp, " x(%lld%+lld)", n->xoffset, n->stkdelta);
if(n->class != 0) {
s = "";
@@ -361,6 +362,8 @@ Vconv(Fmt *fp)
switch(v->ctype) {
case CTINT:
+ if((fp->flags & FmtSharp) || fmtmode == FExp)
+ return fmtprint(fp, "%#B", v->u.xval);
return fmtprint(fp, "%B", v->u.xval);
case CTRUNE:
x = mpgetfix(v->u.xval);
@@ -377,8 +380,14 @@ Vconv(Fmt *fp)
return fmtprint(fp, "%#F", v->u.fval);
case CTCPLX:
if((fp->flags & FmtSharp) || fmtmode == FExp)
- return fmtprint(fp, "(%F+%F)", &v->u.cval->real, &v->u.cval->imag);
- return fmtprint(fp, "(%#F + %#Fi)", &v->u.cval->real, &v->u.cval->imag);
+ return fmtprint(fp, "(%F+%Fi)", &v->u.cval->real, &v->u.cval->imag);
+ if(mpcmpfltc(&v->u.cval->real, 0) == 0)
+ return fmtprint(fp, "%#Fi", &v->u.cval->imag);
+ if(mpcmpfltc(&v->u.cval->imag, 0) == 0)
+ return fmtprint(fp, "%#F", &v->u.cval->real);
+ if(mpcmpfltc(&v->u.cval->imag, 0) < 0)
+ return fmtprint(fp, "(%#F%#Fi)", &v->u.cval->real, &v->u.cval->imag);
+ return fmtprint(fp, "(%#F+%#Fi)", &v->u.cval->real, &v->u.cval->imag);
case CTSTR:
return fmtprint(fp, "\"%Z\"", v->u.sval);
case CTBOOL:
@@ -388,7 +397,7 @@ Vconv(Fmt *fp)
case CTNIL:
return fmtstrcpy(fp, "nil");
}
- return fmtprint(fp, "<%d>", v->ctype);
+ return fmtprint(fp, "<ctype=%d>", v->ctype);
}
// Fmt "%Z": escaped string literals
@@ -516,6 +525,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->prefix, s->name); // (methodsym), typesym, weaksym
case FExp:
+ if(s->name && s->name[0] == '.')
+ fatal("exporting synthetic symbol %s", s->name);
if(s->pkg != builtinpkg)
return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name);
}
@@ -711,12 +722,21 @@ typefmt(Fmt *fp, Type *t)
case TFIELD:
if(!(fp->flags&FmtShort)) {
s = t->sym;
- // Take the name from the original, lest we substituted it with .anon%d
- if (t->nname && (fmtmode == FErr || fmtmode == FExp))
- s = t->nname->orig->sym;
+
+ // Take the name from the original, lest we substituted it with ~anon%d
+ if ((fmtmode == FErr || fmtmode == FExp) && t->nname != N) {
+ if(t->nname->orig != N) {
+ s = t->nname->orig->sym;
+ if(s != S && s->name[0] == '~')
+ s = S;
+ } else
+ s = S;
+ }
if(s != S && !t->embedded) {
- if(fp->flags&FmtLong)
+ if(t->funarg)
+ fmtprint(fp, "%N ", t->nname);
+ else if(fp->flags&FmtLong)
fmtprint(fp, "%hhS ", s); // qualify non-exported names (used on structs, not on funarg)
else
fmtprint(fp, "%S ", s);
@@ -794,6 +814,15 @@ stmtfmt(Fmt *f, Node *n)
switch(n->op){
case ODCL:
+ if(fmtmode == FExp) {
+ switch(n->left->class&~PHEAP) {
+ case PPARAM:
+ case PPARAMOUT:
+ case PAUTO:
+ fmtprint(f, "var %N %T", n->left, n->left->type);
+ goto ret;
+ }
+ }
fmtprint(f, "var %S %T", n->left->sym, n->left->type);
break;
@@ -805,6 +834,12 @@ stmtfmt(Fmt *f, Node *n)
break;
case OAS:
+ // Don't export "v = <N>" initializing statements, hope they're always
+ // preceded by the DCL which will be re-parsed and typecheck to reproduce
+ // the "v = <N>" again.
+ if(fmtmode == FExp && n->right == N)
+ break;
+
if(n->colas && !complexinit)
fmtprint(f, "%N := %N", n->left, n->right);
else
@@ -925,6 +960,7 @@ stmtfmt(Fmt *f, Node *n)
break;
}
+ret:
if(extrablock)
fmtstrcpy(f, "}");
@@ -962,7 +998,6 @@ static int opprec[] = {
[OPAREN] = 8,
[OPRINTN] = 8,
[OPRINT] = 8,
- [ORECV] = 8,
[ORUNESTR] = 8,
[OSTRARRAYBYTE] = 8,
[OSTRARRAYRUNE] = 8,
@@ -994,6 +1029,7 @@ static int opprec[] = {
[OMINUS] = 7,
[OADDR] = 7,
[OIND] = 7,
+ [ORECV] = 7,
[OMUL] = 6,
[ODIV] = 6,
@@ -1055,8 +1091,8 @@ static int
exprfmt(Fmt *f, Node *n, int prec)
{
int nprec;
+ int ptrlit;
NodeList *l;
- Type *t;
while(n && n->implicit && (n->op == OIND || n->op == OADDR))
n = n->left;
@@ -1084,9 +1120,9 @@ exprfmt(Fmt *f, Node *n, int prec)
case OLITERAL: // this is a bit of a mess
if(fmtmode == FErr && n->sym != S)
return fmtprint(f, "%S", n->sym);
- if(n->val.ctype == CTNIL)
- n = n->orig; // if this node was a nil decorated with at type, print the original naked nil
- if(n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) {
+ if(n->val.ctype == CTNIL && n->orig != N && n->orig != n)
+ return exprfmt(f, n->orig, prec);
+ if(n->type != T && n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) {
// Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-.
if(isptr[n->type->etype] || (n->type->etype == TCHAN && n->type->chan == Crecv))
@@ -1097,6 +1133,15 @@ exprfmt(Fmt *f, Node *n, int prec)
return fmtprint(f, "%V", &n->val);
case ONAME:
+ // Special case: name used as local variable in export.
+ switch(n->class&~PHEAP){
+ case PAUTO:
+ case PPARAM:
+ case PPARAMOUT:
+ if(fmtmode == FExp && n->sym && !isblanksym(n->sym) && n->vargen > 0)
+ return fmtprint(f, "%S·%d", n->sym, n->vargen);
+ }
+
// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
// but for export, this should be rendered as (*pkg.T).meth.
// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
@@ -1152,12 +1197,25 @@ exprfmt(Fmt *f, Node *n, int prec)
case OCLOSURE:
if(fmtmode == FErr)
return fmtstrcpy(f, "func literal");
- return fmtprint(f, "%T { %H }", n->type, n->nbody);
+ if(n->nbody)
+ return fmtprint(f, "%T { %H }", n->type, n->nbody);
+ return fmtprint(f, "%T { %H }", n->type, n->closure->nbody);
case OCOMPLIT:
- if(fmtmode == FErr)
+ ptrlit = n->right != N && n->right->implicit && n->right->type && isptr[n->right->type->etype];
+ if(fmtmode == FErr) {
+ if(n->right != N && n->right->type != T && !n->implicit) {
+ if(ptrlit)
+ return fmtprint(f, "&%T literal", n->right->type->type);
+ else
+ return fmtprint(f, "%T literal", n->right->type);
+ }
return fmtstrcpy(f, "composite literal");
- return fmtprint(f, "%N{ %,H }", n->right, n->list);
+ }
+ if(fmtmode == FExp && ptrlit)
+ // typecheck has overwritten OIND by OTYPE with pointer type.
+ return fmtprint(f, "&%T{ %,H }", n->right->type->type, n->list);
+ return fmtprint(f, "(%N{ %,H })", n->right, n->list);
case OPTRLIT:
if(fmtmode == FExp && n->left->implicit)
@@ -1168,24 +1226,18 @@ exprfmt(Fmt *f, Node *n, int prec)
if(fmtmode == FExp) { // requires special handling of field names
if(n->implicit)
fmtstrcpy(f, "{");
- else
- fmtprint(f, "%T{", n->type);
+ else
+ fmtprint(f, "(%T{", n->type);
for(l=n->list; l; l=l->next) {
- // another special case: if n->left is an embedded field of builtin type,
- // it needs to be non-qualified. Can't figure that out in %S, so do it here
- if(l->n->left->type->embedded) {
- t = l->n->left->type->type;
- if(t->sym == S)
- t = t->type;
- fmtprint(f, " %T:%N", t, l->n->right);
- } else
- fmtprint(f, " %hhS:%N", l->n->left->sym, l->n->right);
+ fmtprint(f, " %hhS:%N", l->n->left->sym, l->n->right);
if(l->next)
fmtstrcpy(f, ",");
else
fmtstrcpy(f, " ");
}
+ if(!n->implicit)
+ return fmtstrcpy(f, "})");
return fmtstrcpy(f, "}");
}
// fallthrough
@@ -1196,11 +1248,16 @@ exprfmt(Fmt *f, Node *n, int prec)
return fmtprint(f, "%T literal", n->type);
if(fmtmode == FExp && n->implicit)
return fmtprint(f, "{ %,H }", n->list);
- return fmtprint(f, "%T{ %,H }", n->type, n->list);
+ return fmtprint(f, "(%T{ %,H })", n->type, n->list);
case OKEY:
- if(n->left && n->right)
- return fmtprint(f, "%N:%N", n->left, n->right);
+ if(n->left && n->right) {
+ if(fmtmode == FExp && n->left->type && n->left->type->etype == TFIELD) {
+ // requires special handling of field names
+ return fmtprint(f, "%hhS:%N", n->left->sym, n->right);
+ } else
+ return fmtprint(f, "%N:%N", n->left, n->right);
+ }
if(!n->left && n->right)
return fmtprint(f, ":%N", n->right);
if(n->left && !n->right)
@@ -1260,6 +1317,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case OMAKE:
case ONEW:
case OPANIC:
+ case ORECOVER:
case OPRINT:
case OPRINTN:
if(n->left)
@@ -1408,6 +1466,7 @@ nodedump(Fmt *fp, Node *n)
fmtprint(fp, "%O%J", n->op, n);
break;
case OREGISTER:
+ case OINDREG:
fmtprint(fp, "%O-%R%J", n->op, n->val.u.reg, n);
break;
case OLITERAL:
@@ -1419,6 +1478,10 @@ nodedump(Fmt *fp, Node *n)
fmtprint(fp, "%O-%S%J", n->op, n->sym, n);
else
fmtprint(fp, "%O%J", n->op, n);
+ if(recur && n->type == T && n->ntype) {
+ indent(fp);
+ fmtprint(fp, "%O-ntype%N", n->op, n->ntype);
+ }
break;
case OASOP:
fmtprint(fp, "%O-%O%J", n->op, n->etype, n);
@@ -1629,11 +1692,11 @@ fmtinstallgo(void)
void
dumplist(char *s, NodeList *l)
{
- print("%s\n%+H\n", s, l);
+ print("%s%+H\n", s, l);
}
void
dump(char *s, Node *n)
{
- print("%s [%p]\n%+N\n", s, n, n);
+ print("%s [%p]%+N\n", s, n, n);
}