exprfmt(Fmt *f, Node *n, int prec)
{
int nprec;
+ int ptrlit;
NodeList *l;
while(n && n->implicit && (n->op == OIND || n->op == OADDR))
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");
+ }
+ 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) // handle printing of '&' below.
+ if(fmtmode == FExp && n->left->implicit)
return fmtprint(f, "%N", n->left);
return fmtprint(f, "&%N", n->left);
if(fmtmode == FExp) { // requires special handling of field names
if(n->implicit)
fmtstrcpy(f, "{");
- else if(n->right->implicit)
- fmtprint(f, "&%T{", n->type);
else
fmtprint(f, "(%T{", n->type);
for(l=n->list; l; l=l->next) {
else
fmtstrcpy(f, " ");
}
- if(!n->implicit && !n->right->implicit)
+ if(!n->implicit)
return fmtstrcpy(f, "})");
return fmtstrcpy(f, "}");
}
return fmtprint(f, "%T literal", n->type);
if(fmtmode == FExp && n->implicit)
return fmtprint(f, "{ %,H }", n->list);
- if(fmtmode == FExp && n->right->implicit)
- 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)
case OCONV:
doconv:
ok |= Erv;
- l = nod(OXXX, N, N);
- n->orig = l;
- *l = *n;
+ saveorignode(n);
typecheck(&n->left, Erv | (top & (Eindir | Eiota)));
convlit1(&n->left, n->type, 1);
if((t = n->left->type) == T || n->type == T)
typecheckcomplit(Node **np)
{
int bad, i, len, nerr;
- Node *l, *n, *r, **hash;
+ Node *l, *n, *norig, *r, **hash;
NodeList *ll;
Type *t, *f;
Sym *s, *s1;
yyerror("missing type in composite literal");
goto error;
}
-
+
+ // Save original node (including n->right)
+ norig = nod(n->op, N, N);
+ *norig = *n;
+
setlineno(n->right);
l = typecheck(&n->right /* sic */, Etype|Ecomplit);
if((t = l->type) == T)
goto error;
nerr = nerrors;
n->type = t;
-
+
if(isptr[t->etype]) {
// For better or worse, we don't allow pointers as the composite literal type,
// except when using the &T syntax, which sets implicit on the OIND.
if(t->bound < 0)
n->right = nodintconst(len);
n->op = OARRAYLIT;
- // restore implicitness.
- if(isptr[n->type->etype])
- n->right->implicit = 1;
break;
case TMAP:
if(nerr != nerrors)
goto error;
+ n->orig = norig;
if(isptr[n->type->etype]) {
n = nod(OPTRLIT, n, N);
n->typecheck = 1;
n->left->typecheck = 1;
}
+ n->orig = norig;
*np = n;
lineno = lno;
return;