Commit 419c53af authored by Luuk van Dijk's avatar Luuk van Dijk

gc: don't print implicit type on struct literal in export

As pointed out in the discussion around 2678.

R=rsc
CC=golang-dev
https://golang.org/cl/5534077
parent fb86bbe2
...@@ -1150,11 +1150,16 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -1150,11 +1150,16 @@ exprfmt(Fmt *f, Node *n, int prec)
return fmtprint(f, "%N{ %,H }", n->right, n->list); return fmtprint(f, "%N{ %,H }", n->right, n->list);
case OPTRLIT: case OPTRLIT:
if (fmtmode == FExp && n->left->right->implicit == Implicit)
return fmtprint(f, "%N", n->left);
return fmtprint(f, "&%N", n->left); return fmtprint(f, "&%N", n->left);
case OSTRUCTLIT: case OSTRUCTLIT:
if (fmtmode == FExp) { // requires special handling of field names if (fmtmode == FExp) { // requires special handling of field names
fmtprint(f, "%T{", n->type); if(n->right->implicit == Implicit)
fmtstrcpy(f, "{");
else
fmtprint(f, "%T{", n->type);
for(l=n->list; l; l=l->next) { for(l=n->list; l; l=l->next) {
// another special case: if n->left is an embedded field of builtin type, // 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 // it needs to be non-qualified. Can't figure that out in %S, so do it here
...@@ -1411,7 +1416,7 @@ nodedump(Fmt *fp, Node *n) ...@@ -1411,7 +1416,7 @@ nodedump(Fmt *fp, Node *n)
fmtprint(fp, "%O-%O%J", n->op, n->etype, n); fmtprint(fp, "%O-%O%J", n->op, n->etype, n);
break; break;
case OTYPE: case OTYPE:
fmtprint(fp, "%O %S type=%T", n->op, n->sym, n->type); fmtprint(fp, "%O %S%J type=%T", n->op, n->sym, n, n->type);
if(recur && n->type == T && n->ntype) { if(recur && n->type == T && n->ntype) {
indent(fp); indent(fp);
fmtprint(fp, "%O-ntype%N", n->op, n->ntype); fmtprint(fp, "%O-ntype%N", n->op, n->ntype);
......
...@@ -217,6 +217,13 @@ enum ...@@ -217,6 +217,13 @@ enum
EscNever, EscNever,
}; };
enum
{
Explicit,
Implicit, // don't print in output
ImplPtr, // OIND added by &T{ ... } literal
};
struct Node struct Node
{ {
// Tree structure. // Tree structure.
...@@ -252,7 +259,7 @@ struct Node ...@@ -252,7 +259,7 @@ struct Node
uchar used; uchar used;
uchar isddd; uchar isddd;
uchar readonly; uchar readonly;
uchar implicit; // don't show in printout uchar implicit; // Explicit, Implicit, ImplPtr.
uchar addrtaken; // address taken, even if not moved to heap uchar addrtaken; // address taken, even if not moved to heap
uchar dupok; // duplicate definitions ok (for func) uchar dupok; // duplicate definitions ok (for func)
......
...@@ -808,7 +808,7 @@ uexpr: ...@@ -808,7 +808,7 @@ uexpr:
// Special case for &T{...}: turn into (*T){...}. // Special case for &T{...}: turn into (*T){...}.
$$ = $2; $$ = $2;
$$->right = nod(OIND, $$->right, N); $$->right = nod(OIND, $$->right, N);
$$->right->implicit = 1; $$->right->implicit = ImplPtr;
} else { } else {
$$ = nod(OADDR, $2, N); $$ = nod(OADDR, $2, N);
} }
......
...@@ -2047,10 +2047,9 @@ typecheckcomplit(Node **np) ...@@ -2047,10 +2047,9 @@ typecheckcomplit(Node **np)
n->type = t; n->type = t;
if(isptr[t->etype]) { if(isptr[t->etype]) {
// For better or worse, we don't allow pointers as // For better or worse, we don't allow pointers as the composite literal type,
// the composite literal type, except when using // except when using the &T syntax, which sets implicit to ImplPtr.
// the &T syntax, which sets implicit. if(n->right->implicit == Explicit) {
if(!n->right->implicit) {
yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type); yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
goto error; goto error;
} }
......
...@@ -3232,7 +3232,7 @@ yyreduce: ...@@ -3232,7 +3232,7 @@ yyreduce:
// Special case for &T{...}: turn into (*T){...}. // Special case for &T{...}: turn into (*T){...}.
(yyval.node) = (yyvsp[(2) - (2)].node); (yyval.node) = (yyvsp[(2) - (2)].node);
(yyval.node)->right = nod(OIND, (yyval.node)->right, N); (yyval.node)->right = nod(OIND, (yyval.node)->right, N);
(yyval.node)->right->implicit = 1; (yyval.node)->right->implicit = ImplPtr;
} else { } else {
(yyval.node) = nod(OADDR, (yyvsp[(2) - (2)].node), N); (yyval.node) = nod(OADDR, (yyvsp[(2) - (2)].node), N);
} }
......
...@@ -20,3 +20,22 @@ func F3() (ret []int) { return append(ret, 1) } ...@@ -20,3 +20,22 @@ func F3() (ret []int) { return append(ret, 1) }
// Call of inlined method with blank receiver. // Call of inlined method with blank receiver.
func (_ *T) M() int { return 1 } func (_ *T) M() int { return 1 }
func (t *T) MM() int { return t.M() } func (t *T) MM() int { return t.M() }
// One more like issue 2678
type S struct { x, y int }
type U []S
func F4(S int) U { return U{{S,S}} }
func F5() []*S {
return []*S{ {1,2}, { 3, 4} }
}
func F6(S int) *U {
return &U{{S,S}}
}
...@@ -13,6 +13,7 @@ func use() { ...@@ -13,6 +13,7 @@ func use() {
one.F1(nil) one.F1(nil)
one.F2(nil) one.F2(nil)
one.F3() one.F3()
one.F4(1)
var t *one.T var t *one.T
t.M() t.M()
......
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