summaryrefslogtreecommitdiff
path: root/src/cmd/gc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc')
-rw-r--r--src/cmd/gc/builtin.c6
-rw-r--r--src/cmd/gc/closure.c179
-rw-r--r--src/cmd/gc/const.c35
-rw-r--r--src/cmd/gc/cplx.c8
-rw-r--r--src/cmd/gc/dcl.c48
-rw-r--r--src/cmd/gc/esc.c13
-rw-r--r--src/cmd/gc/fmt.c6
-rw-r--r--src/cmd/gc/gen.c5
-rw-r--r--src/cmd/gc/go.h11
-rw-r--r--src/cmd/gc/go.y5
-rw-r--r--src/cmd/gc/inl.c31
-rw-r--r--src/cmd/gc/lex.c1
-rw-r--r--src/cmd/gc/obj.c14
-rw-r--r--src/cmd/gc/racewalk.c66
-rw-r--r--src/cmd/gc/range.c4
-rw-r--r--src/cmd/gc/reflect.c31
-rw-r--r--src/cmd/gc/subr.c15
-rw-r--r--src/cmd/gc/swt.c4
-rw-r--r--src/cmd/gc/typecheck.c201
-rw-r--r--src/cmd/gc/walk.c136
-rw-r--r--src/cmd/gc/y.tab.c505
21 files changed, 913 insertions, 411 deletions
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
index 7de448d1e..f1d0931d4 100644
--- a/src/cmd/gc/builtin.c
+++ b/src/cmd/gc/builtin.c
@@ -63,7 +63,13 @@ char *runtimeimport =
"func @\"\".equal (@\"\".typ·2 *byte, @\"\".x1·3 any, @\"\".x2·4 any) (@\"\".ret·1 bool)\n"
"func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64) (@\"\".hmap·1 map[any]any)\n"
"func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 any)\n"
+ "func @\"\".mapaccess1_fast32 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
+ "func @\"\".mapaccess1_fast64 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
+ "func @\"\".mapaccess1_faststr (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
"func @\"\".mapaccess2 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 any, @\"\".pres·2 bool)\n"
+ "func @\"\".mapaccess2_fast32 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
+ "func @\"\".mapaccess2_fast64 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
+ "func @\"\".mapaccess2_faststr (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
"func @\"\".mapassign1 (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 any, @\"\".val·4 any)\n"
"func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *any)\n"
"func @\"\".mapdelete (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 any)\n"
diff --git a/src/cmd/gc/closure.c b/src/cmd/gc/closure.c
index 4e029ef83..aca30dc1c 100644
--- a/src/cmd/gc/closure.c
+++ b/src/cmd/gc/closure.c
@@ -60,6 +60,7 @@ closurebody(NodeList *body)
func = curfn;
func->nbody = body;
+ func->endlineno = lineno;
funcbody(func);
// closure-specific variables are hanging off the
@@ -154,6 +155,7 @@ makeclosure(Node *func, int nowrap)
declare(xfunc->nname, PFUNC);
xfunc->nname->funcdepth = func->funcdepth;
xfunc->funcdepth = func->funcdepth;
+ xfunc->endlineno = func->endlineno;
// declare variables holding addresses taken from closure
// and initialize in entry prologue.
@@ -255,26 +257,167 @@ walkclosure(Node *func, NodeList **init)
return clos;
}
-// Special case for closures that get called in place.
-// Optimize runtime.closure(X, __func__xxxx_, .... ) away
-// to __func__xxxx_(Y ....).
-// On entry, expect n->op == OCALL, n->left->op == OCLOSURE.
+static Node *makepartialcall(Node*, Type*, Node*);
+
void
-walkcallclosure(Node *n, NodeList **init)
+typecheckpartialcall(Node *fn, Node *sym)
+{
+ switch(fn->op) {
+ case ODOTINTER:
+ case ODOTMETH:
+ break;
+ default:
+ fatal("invalid typecheckpartialcall");
+ }
+
+ // Create top-level function.
+ fn->nname = makepartialcall(fn, fn->type, sym);
+ fn->right = sym;
+ fn->op = OCALLPART;
+ fn->type = fn->nname->type;
+}
+
+static Node*
+makepartialcall(Node *fn, Type *t0, Node *meth)
{
- USED(init);
- if (n->op != OCALLFUNC || n->left->op != OCLOSURE) {
- dump("walkcallclosure", n);
- fatal("abuse of walkcallclosure");
+ Node *ptr, *n, *call, *xtype, *xfunc, *cv;
+ Type *rcvrtype, *basetype, *t;
+ NodeList *body, *l, *callargs, *retargs;
+ char *p;
+ Sym *sym;
+ int i;
+
+ // TODO: names are not right
+ rcvrtype = fn->left->type;
+ if(exportname(meth->sym->name))
+ p = smprint("%-hT.%s·fm", rcvrtype, meth->sym->name);
+ else
+ p = smprint("%-hT.(%-S)·fm", rcvrtype, meth->sym);
+ basetype = rcvrtype;
+ if(isptr[rcvrtype->etype])
+ basetype = basetype->type;
+ if(basetype->sym == S)
+ fatal("missing base type for %T", rcvrtype);
+
+ sym = pkglookup(p, basetype->sym->pkg);
+ free(p);
+ if(sym->flags & SymUniq)
+ return sym->def;
+ sym->flags |= SymUniq;
+
+ xtype = nod(OTFUNC, N, N);
+ i = 0;
+ l = nil;
+ callargs = nil;
+ xfunc = nod(ODCLFUNC, N, N);
+ for(t = getinargx(t0)->type; t; t = t->down) {
+ snprint(namebuf, sizeof namebuf, "a%d", i++);
+ n = newname(lookup(namebuf));
+ n->class = PPARAM;
+ xfunc->dcl = list(xfunc->dcl, n);
+ callargs = list(callargs, n);
+ l = list(l, nod(ODCLFIELD, n, typenod(t->type)));
}
+ xtype->list = l;
+ i = 0;
+ l = nil;
+ retargs = nil;
+ for(t = getoutargx(t0)->type; t; t = t->down) {
+ snprint(namebuf, sizeof namebuf, "r%d", i++);
+ n = newname(lookup(namebuf));
+ n->class = PPARAMOUT;
+ xfunc->dcl = list(xfunc->dcl, n);
+ retargs = list(retargs, n);
+ l = list(l, nod(ODCLFIELD, n, typenod(t->type)));
+ }
+ xtype->rlist = l;
- // New arg list for n. First the closure-args
- // and then the original parameter list.
- n->list = concat(n->left->enter, n->list);
- n->left = n->left->closure->nname;
- dowidth(n->left->type);
- n->type = getoutargx(n->left->type);
- // for a single valued function, pull the field type out of the struct
- if (n->type && n->type->type && !n->type->type->down)
- n->type = n->type->type->type;
+ xfunc->dupok = 1;
+ xfunc->nname = newname(sym);
+ xfunc->nname->sym->flags |= SymExported; // disable export
+ xfunc->nname->ntype = xtype;
+ xfunc->nname->defn = xfunc;
+ declare(xfunc->nname, PFUNC);
+
+ // Declare and initialize variable holding receiver.
+ body = nil;
+ cv = nod(OCLOSUREVAR, N, N);
+ cv->xoffset = widthptr;
+ cv->type = rcvrtype;
+ ptr = nod(ONAME, N, N);
+ ptr->sym = lookup("rcvr");
+ ptr->class = PAUTO;
+ ptr->addable = 1;
+ ptr->ullman = 1;
+ ptr->used = 1;
+ ptr->curfn = xfunc;
+ xfunc->dcl = list(xfunc->dcl, ptr);
+ if(isptr[rcvrtype->etype] || isinter(rcvrtype)) {
+ ptr->ntype = typenod(rcvrtype);
+ body = list(body, nod(OAS, ptr, cv));
+ } else {
+ ptr->ntype = typenod(ptrto(rcvrtype));
+ body = list(body, nod(OAS, ptr, nod(OADDR, cv, N)));
+ }
+
+ call = nod(OCALL, nod(OXDOT, ptr, meth), N);
+ call->list = callargs;
+ if(t0->outtuple == 0) {
+ body = list(body, call);
+ } else {
+ n = nod(OAS2, N, N);
+ n->list = retargs;
+ n->rlist = list1(call);
+ body = list(body, n);
+ n = nod(ORETURN, N, N);
+ body = list(body, n);
+ }
+
+ xfunc->nbody = body;
+
+ typecheck(&xfunc, Etop);
+ sym->def = xfunc;
+ xtop = list(xtop, xfunc);
+
+ return xfunc;
+}
+
+Node*
+walkpartialcall(Node *n, NodeList **init)
+{
+ Node *clos, *typ;
+
+ // Create closure in the form of a composite literal.
+ // For x.M with receiver (x) type T, the generated code looks like:
+ //
+ // clos = &struct{F uintptr; R T}{M.T·f, x}
+ //
+ // Like walkclosure above.
+
+ if(isinter(n->left->type)) {
+ n->left = cheapexpr(n->left, init);
+ checknotnil(n->left, init);
+ }
+
+ typ = nod(OTSTRUCT, N, N);
+ typ->list = list1(nod(ODCLFIELD, newname(lookup("F")), typenod(types[TUINTPTR])));
+ typ->list = list(typ->list, nod(ODCLFIELD, newname(lookup("R")), typenod(n->left->type)));
+
+ clos = nod(OCOMPLIT, N, nod(OIND, typ, N));
+ clos->esc = n->esc;
+ clos->right->implicit = 1;
+ clos->list = list1(nod(OCFUNC, n->nname->nname, N));
+ clos->list = list(clos->list, n->left);
+
+ // Force type conversion from *struct to the func type.
+ clos = nod(OCONVNOP, clos, N);
+ clos->type = n->type;
+
+ typecheck(&clos, Erv);
+ // typecheck will insert a PTRLIT node under CONVNOP,
+ // tag it with escape analysis result.
+ clos->left->esc = n->esc;
+ walkexpr(&clos, init);
+
+ return clos;
}
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index 4f1ff6778..add438daf 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -119,6 +119,27 @@ convlit1(Node **np, Type *t, int explicit)
}
n->type = t;
return;
+ case OCOMPLEX:
+ if(n->type->etype == TIDEAL) {
+ switch(t->etype) {
+ default:
+ // If trying to convert to non-complex type,
+ // leave as complex128 and let typechecker complain.
+ t = types[TCOMPLEX128];
+ //fallthrough
+ case TCOMPLEX128:
+ n->type = t;
+ convlit(&n->left, types[TFLOAT64]);
+ convlit(&n->right, types[TFLOAT64]);
+ break;
+ case TCOMPLEX64:
+ n->type = t;
+ convlit(&n->left, types[TFLOAT32]);
+ convlit(&n->right, types[TFLOAT32]);
+ break;
+ }
+ }
+ return;
}
// avoided repeated calculations, errors
@@ -1068,6 +1089,11 @@ idealkind(Node *n)
return k1;
else
return k2;
+ case OREAL:
+ case OIMAG:
+ return CTFLT;
+ case OCOMPLEX:
+ return CTCPLX;
case OADDSTR:
return CTSTR;
case OANDAND:
@@ -1185,6 +1211,7 @@ void
defaultlit2(Node **lp, Node **rp, int force)
{
Node *l, *r;
+ int lkind, rkind;
l = *lp;
r = *rp;
@@ -1204,18 +1231,20 @@ defaultlit2(Node **lp, Node **rp, int force)
convlit(lp, types[TBOOL]);
convlit(rp, types[TBOOL]);
}
- if(isconst(l, CTCPLX) || isconst(r, CTCPLX)) {
+ lkind = idealkind(l);
+ rkind = idealkind(r);
+ if(lkind == CTCPLX || rkind == CTCPLX) {
convlit(lp, types[TCOMPLEX128]);
convlit(rp, types[TCOMPLEX128]);
return;
}
- if(isconst(l, CTFLT) || isconst(r, CTFLT)) {
+ if(lkind == CTFLT || rkind == CTFLT) {
convlit(lp, types[TFLOAT64]);
convlit(rp, types[TFLOAT64]);
return;
}
- if(isconst(l, CTRUNE) || isconst(r, CTRUNE)) {
+ if(lkind == CTRUNE || rkind == CTRUNE) {
convlit(lp, runetype);
convlit(rp, runetype);
return;
diff --git a/src/cmd/gc/cplx.c b/src/cmd/gc/cplx.c
index e0127fc59..c9bab7a76 100644
--- a/src/cmd/gc/cplx.c
+++ b/src/cmd/gc/cplx.c
@@ -36,7 +36,7 @@ void
complexmove(Node *f, Node *t)
{
int ft, tt;
- Node n1, n2, n3, n4;
+ Node n1, n2, n3, n4, tmp;
if(debug['g']) {
dump("\ncomplexmove-f", f);
@@ -62,9 +62,9 @@ complexmove(Node *f, Node *t)
// make f addable.
// also use temporary if possible stack overlap.
if(!f->addable || overlap(f, t)) {
- tempname(&n1, f->type);
- complexmove(f, &n1);
- f = &n1;
+ tempname(&tmp, f->type);
+ complexmove(f, &tmp);
+ f = &tmp;
}
subnode(&n1, &n2, f);
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index aa2489d9a..429f212e7 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -225,8 +225,12 @@ declare(Node *n, int ctxt)
if(ctxt == PAUTO)
n->xoffset = 0;
- if(s->block == block)
- redeclare(s, "in this block");
+ if(s->block == block) {
+ // functype will print errors about duplicate function arguments.
+ // Don't repeat the error here.
+ if(ctxt != PPARAM && ctxt != PPARAMOUT)
+ redeclare(s, "in this block");
+ }
s->block = block;
s->lastlineno = parserline();
@@ -824,22 +828,24 @@ structfield(Node *n)
return f;
}
+static uint32 uniqgen;
+
static void
checkdupfields(Type *t, char* what)
{
- Type* t1;
int lno;
lno = lineno;
- for( ; t; t=t->down)
- if(t->sym && t->nname && !isblank(t->nname))
- for(t1=t->down; t1; t1=t1->down)
- if(t1->sym == t->sym) {
- lineno = t->nname->lineno;
- yyerror("duplicate %s %s", what, t->sym->name);
- break;
- }
+ for( ; t; t=t->down) {
+ if(t->sym && t->nname && !isblank(t->nname)) {
+ if(t->sym->uniqgen == uniqgen) {
+ lineno = t->nname->lineno;
+ yyerror("duplicate %s %s", what, t->sym->name);
+ } else
+ t->sym->uniqgen = uniqgen;
+ }
+ }
lineno = lno;
}
@@ -865,6 +871,7 @@ tostruct(NodeList *l)
if(f->broke)
t->broke = 1;
+ uniqgen++;
checkdupfields(t->type, "field");
if (!t->broke)
@@ -897,7 +904,6 @@ tofunargs(NodeList *l)
if(f->broke)
t->broke = 1;
- checkdupfields(t->type, "argument");
return t;
}
@@ -1004,6 +1010,7 @@ tointerface(NodeList *l)
if(f->broke)
t->broke = 1;
+ uniqgen++;
checkdupfields(t->type, "method");
t = sortinter(t);
checkwidth(t);
@@ -1187,6 +1194,11 @@ functype(Node *this, NodeList *in, NodeList *out)
t->type->down = tofunargs(out);
t->type->down->down = tofunargs(in);
+ uniqgen++;
+ checkdupfields(t->type->type, "argument");
+ checkdupfields(t->type->down->type, "argument");
+ checkdupfields(t->type->down->down->type, "argument");
+
if (t->type->broke || t->type->down->broke || t->type->down->down->broke)
t->broke = 1;
@@ -1368,6 +1380,12 @@ addmethod(Sym *sf, Type *t, int local, int nointerface)
}
}
+ if(local && !pa->local) {
+ // defining method on non-local type.
+ yyerror("cannot define new methods on non-local type %T", pa);
+ return;
+ }
+
n = nod(ODCLFIELD, newname(sf), N);
n->type = t;
@@ -1383,12 +1401,6 @@ addmethod(Sym *sf, Type *t, int local, int nointerface)
return;
}
- if(local && !pa->local) {
- // defining method on non-local type.
- yyerror("cannot define new methods on non-local type %T", pa);
- return;
- }
-
f = structfield(n);
f->nointerface = nointerface;
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
index 46c06d10e..df273e392 100644
--- a/src/cmd/gc/esc.c
+++ b/src/cmd/gc/esc.c
@@ -596,6 +596,14 @@ esc(EscState *e, Node *n)
// Contents make it to memory, lose track.
escassign(e, &e->theSink, n->left);
break;
+
+ case OCALLPART:
+ n->esc = EscNone; // until proven otherwise
+ e->noesc = list(e->noesc, n);
+ n->escloopdepth = e->loopdepth;
+ // Contents make it to memory, lose track.
+ escassign(e, &e->theSink, n->left);
+ break;
case OMAPLIT:
n->esc = EscNone; // until proven otherwise
@@ -667,6 +675,7 @@ escassign(EscState *e, Node *dst, Node *src)
case OCONVNOP:
case OMAPLIT:
case OSTRUCTLIT:
+ case OCALLPART:
break;
case ONAME:
@@ -713,6 +722,7 @@ escassign(EscState *e, Node *dst, Node *src)
case OMAKESLICE:
case ONEW:
case OCLOSURE:
+ case OCALLPART:
escflows(e, dst, src);
break;
@@ -1033,7 +1043,7 @@ escwalk(EscState *e, int level, Node *dst, Node *src)
switch(src->op) {
case ONAME:
- if(src->class == PPARAM && leaks && src->esc != EscHeap) {
+ if(src->class == PPARAM && (leaks || dst->escloopdepth < 0) && src->esc != EscHeap) {
src->esc = EscScope;
if(debug['m'])
warnl(src->lineno, "leaking param: %hN", src);
@@ -1073,6 +1083,7 @@ escwalk(EscState *e, int level, Node *dst, Node *src)
case OMAPLIT:
case ONEW:
case OCLOSURE:
+ case OCALLPART:
if(leaks) {
src->esc = EscHeap;
if(debug['m'])
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
index ab81e6c88..ee5b9e939 100644
--- a/src/cmd/gc/fmt.c
+++ b/src/cmd/gc/fmt.c
@@ -168,7 +168,7 @@ Lconv(Fmt *fp)
lno = a[i].incl->line - 1; // now print out start of this file
}
if(n == 0)
- fmtprint(fp, "<epoch>");
+ fmtprint(fp, "<unknown line number>");
return 0;
}
@@ -1022,6 +1022,7 @@ static int opprec[] = {
[ODOTTYPE] = 8,
[ODOT] = 8,
[OXDOT] = 8,
+ [OCALLPART] = 8,
[OPLUS] = 7,
[ONOT] = 7,
@@ -1269,9 +1270,10 @@ exprfmt(Fmt *f, Node *n, int prec)
case ODOTPTR:
case ODOTINTER:
case ODOTMETH:
+ case OCALLPART:
exprfmt(f, n->left, nprec);
if(n->right == N || n->right->sym == S)
- fmtstrcpy(f, ".<nil>");
+ return fmtstrcpy(f, ".<nil>");
return fmtprint(f, ".%hhS", n->right->sym);
case ODOTTYPE:
diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c
index 5f03d9476..b47a04bf0 100644
--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -491,6 +491,9 @@ gen(Node *n)
case ORETURN:
cgen_ret(n);
break;
+
+ case OCHECKNOTNIL:
+ checkref(n->left, 1);
}
ret:
@@ -807,7 +810,7 @@ cgen_slice(Node *n, Node *res)
if(n->op == OSLICEARR) {
if(!isptr[n->left->type->etype])
fatal("slicearr is supposed to work on pointer: %+N\n", n);
- checkref(n->left);
+ checkref(n->left, 0);
}
if(isnil(n->left)) {
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index f86c152f2..6be0ec8c9 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -268,6 +268,7 @@ struct Node
uchar addrtaken; // address taken, even if not moved to heap
uchar dupok; // duplicate definitions ok (for func)
schar likely; // likeliness of if statement
+ uchar hasbreak; // has break statement
// most nodes
Type* type;
@@ -368,6 +369,7 @@ struct Sym
uchar sym; // huffman encoding in object file
Sym* link;
int32 npkg; // number of imported packages with this name
+ uint32 uniqgen;
// saved and restored by dcopy
Pkg* pkg;
@@ -450,6 +452,7 @@ enum
OCALLFUNC, // f()
OCALLMETH, // t.Method()
OCALLINTER, // err.Error()
+ OCALLPART, // t.Method (without ())
OCAP, // cap
OCLOSE, // close
OCLOSURE, // f = func() { etc }
@@ -562,6 +565,7 @@ enum
OITAB, // itable word of an interface value.
OCLOSUREVAR, // variable reference at beginning of closure function
OCFUNC, // reference to c function pointer (not go func value)
+ OCHECKNOTNIL, // emit code to ensure pointer/interface not nil
// arch-specific registers
OREGISTER, // a register, such as AX.
@@ -987,7 +991,8 @@ Node* closurebody(NodeList *body);
void closurehdr(Node *ntype);
void typecheckclosure(Node *func, int top);
Node* walkclosure(Node *func, NodeList **init);
-void walkcallclosure(Node *n, NodeList **init);
+void typecheckpartialcall(Node*, Node*);
+Node* walkpartialcall(Node*, NodeList**);
/*
* const.c
@@ -1363,6 +1368,7 @@ Node* typecheck(Node **np, int top);
void typechecklist(NodeList *l, int top);
Node* typecheckdef(Node *n);
void copytype(Node *n, Type *t);
+void checkreturn(Node*);
void queuemethod(Node *n);
/*
@@ -1416,7 +1422,8 @@ EXTERN Node* nodfp;
int anyregalloc(void);
void betypeinit(void);
void bgen(Node *n, int true, int likely, Prog *to);
-void checkref(Node*);
+void checkref(Node *n, int force);
+void checknotnil(Node*, NodeList**);
void cgen(Node*, Node*);
void cgen_asop(Node *n);
void cgen_call(Node *n, int proc);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 794961e8e..a12da5671 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -536,7 +536,10 @@ compound_stmt:
}
stmt_list '}'
{
- $$ = liststmt($3);
+ if($3 == nil)
+ $$ = nod(OEMPTY, N, N);
+ else
+ $$ = liststmt($3);
popdcl();
}
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c
index 1cc13a304..850bb36ec 100644
--- a/src/cmd/gc/inl.c
+++ b/src/cmd/gc/inl.c
@@ -357,7 +357,7 @@ inlnode(Node **np)
}
case OCLOSURE:
- // TODO do them here (or earlier) instead of in walkcallclosure,
+ // TODO do them here (or earlier),
// so escape analysis can avoid more heapmoves.
return;
}
@@ -565,24 +565,31 @@ mkinlcall1(Node **np, Node *fn, int isddd)
inlretvars = nil;
i = 0;
// Make temp names to use instead of the originals
- for(ll = dcl; ll; ll=ll->next)
+ for(ll = dcl; ll; ll=ll->next) {
+ if(ll->n->class == PPARAMOUT) // return values handled below.
+ continue;
if(ll->n->op == ONAME) {
ll->n->inlvar = inlvar(ll->n);
// Typecheck because inlvar is not necessarily a function parameter.
typecheck(&ll->n->inlvar, Erv);
if ((ll->n->class&~PHEAP) != PAUTO)
ninit = list(ninit, nod(ODCL, ll->n->inlvar, N)); // otherwise gen won't emit the allocations for heapallocs
- if (ll->n->class == PPARAMOUT) // we rely on the order being correct here
- inlretvars = list(inlretvars, ll->n->inlvar);
}
+ }
- // anonymous return values, synthesize names for use in assignment that replaces return
- if(inlretvars == nil && fn->type->outtuple > 0)
- for(t = getoutargx(fn->type)->type; t; t = t->down) {
+ // temporaries for return values.
+ for(t = getoutargx(fn->type)->type; t; t = t->down) {
+ if(t != T && t->nname != N && !isblank(t->nname)) {
+ m = inlvar(t->nname);
+ typecheck(&m, Erv);
+ t->nname->inlvar = m;
+ } else {
+ // anonymous return values, synthesize names for use in assignment that replaces return
m = retvar(t, i++);
- ninit = list(ninit, nod(ODCL, m, N));
- inlretvars = list(inlretvars, m);
}
+ ninit = list(ninit, nod(ODCL, m, N));
+ inlretvars = list(inlretvars, m);
+ }
// assign receiver.
if(fn->type->thistuple && n->left->op == ODOTMETH) {
@@ -790,6 +797,12 @@ inlvar(Node *var)
n->class = PAUTO;
n->used = 1;
n->curfn = curfn; // the calling function, not the called one
+
+ // esc pass wont run if we're inlining into a iface wrapper
+ // luckily, we can steal the results from the target func
+ if(var->esc == EscHeap)
+ addrescapes(n);
+
curfn->dcl = list(curfn->dcl, n);
return n;
}
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 68ae6864d..118a0d7a0 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -376,6 +376,7 @@ main(int argc, char *argv[])
curfn = l->n;
saveerrors();
typechecklist(l->n->nbody, Etop);
+ checkreturn(l->n);
if(nerrors != 0)
l->n->nbody = nil; // type errors; do not compile
}
diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c
index b87d35b7b..e4bcd1170 100644
--- a/src/cmd/gc/obj.c
+++ b/src/cmd/gc/obj.c
@@ -16,6 +16,8 @@ static void dumpglobls(void);
void
dumpobj(void)
{
+ NodeList *externs, *tmp;
+
bout = Bopen(outfile, OWRITE);
if(bout == nil) {
flusherrors();
@@ -31,8 +33,20 @@ dumpobj(void)
outhist(bout);
+ externs = nil;
+ if(externdcl != nil)
+ externs = externdcl->end;
+
dumpglobls();
dumptypestructs();
+
+ // Dump extra globals.
+ tmp = externdcl;
+ if(externs != nil)
+ externdcl = externs->next;
+ dumpglobls();
+ externdcl = tmp;
+
dumpdata();
dumpfuncs();
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index bae98ec1b..3e5e592ca 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -196,6 +196,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
case OPLUS:
case OREAL:
case OIMAG:
+ case OCOM:
racewalknode(&n->left, init, wr, 0);
goto ret;
@@ -222,23 +223,17 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
case OCAP:
racewalknode(&n->left, init, 0, 0);
if(istype(n->left->type, TMAP)) {
- // crashes on len(m[0]) or len(f())
- SET(n1);
- USED(n1);
- /*
- n1 = nod(OADDR, n->left, N);
- n1 = conv(n1, types[TUNSAFEPTR]);
- n1 = conv(n1, ptrto(ptrto(types[TINT8])));
- n1 = nod(OIND, n1, N);
+ n1 = nod(OCONVNOP, n->left, N);
+ n1->type = ptrto(types[TUINT8]);
n1 = nod(OIND, n1, N);
typecheck(&n1, Erv);
callinstr(&n1, init, 0, skip);
- */
}
goto ret;
case OLSH:
case ORSH:
+ case OLROT:
case OAND:
case OANDNOT:
case OOR:
@@ -279,7 +274,6 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
case ODIV:
case OMOD:
- // TODO(dvyukov): add a test for this
racewalknode(&n->left, init, wr, 0);
racewalknode(&n->right, init, wr, 0);
goto ret;
@@ -324,9 +318,30 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
case OPANIC:
case ORECOVER:
case OCONVIFACE:
+ case OMAKECHAN:
+ case OMAKEMAP:
+ case OMAKESLICE:
+ case OCALL:
+ case OCOPY:
+ case ORUNESTR:
+ case OARRAYBYTESTR:
+ case OARRAYRUNESTR:
+ case OSTRARRAYBYTE:
+ case OSTRARRAYRUNE:
+ case OINDEXMAP: // lowered to call
+ case OCMPSTR:
+ case OADDSTR:
+ case ODOTTYPE:
+ case ODOTTYPE2:
yyerror("racewalk: %O must be lowered by now", n->op);
goto ret;
+ // impossible nodes: only appear in backend.
+ case ORROTC:
+ case OEXTEND:
+ yyerror("racewalk: %O cannot exist now", n->op);
+ goto ret;
+
// just do generic traversal
case OFOR:
case OIF:
@@ -334,43 +349,28 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
case ORETURN:
case OSELECT:
case OEMPTY:
+ case OBREAK:
+ case OCONTINUE:
+ case OFALL:
+ case OGOTO:
+ case OLABEL:
goto ret;
// does not require instrumentation
- case OINDEXMAP: // implemented in runtime
case OPRINT: // don't bother instrumenting it
case OPRINTN: // don't bother instrumenting it
case OPARAM: // it appears only in fn->exit to copy heap params back
goto ret;
// unimplemented
- case OCMPSTR:
- case OADDSTR:
case OSLICESTR:
case OAPPEND:
- case OCOPY:
- case OMAKECHAN:
- case OMAKEMAP:
- case OMAKESLICE:
- case ORUNESTR:
- case OARRAYBYTESTR:
- case OARRAYRUNESTR:
- case OSTRARRAYBYTE:
- case OSTRARRAYRUNE:
case OCMPIFACE:
case OARRAYLIT:
case OMAPLIT:
case OSTRUCTLIT:
case OCLOSURE:
- case ODOTTYPE:
- case ODOTTYPE2:
- case OCALL:
- case OBREAK:
case ODCL:
- case OCONTINUE:
- case OFALL:
- case OGOTO:
- case OLABEL:
case ODCLCONST:
case ODCLTYPE:
case OLITERAL:
@@ -378,13 +378,11 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
case OTYPE:
case ONONAME:
case OINDREG:
- case OCOM:
case ODOTMETH:
case OITAB:
- case OEXTEND:
case OHMUL:
- case OLROT:
- case ORROTC:
+ case OCHECKNOTNIL:
+ case OCLOSUREVAR:
goto ret;
}
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c
index 50c4617c0..e80a8c723 100644
--- a/src/cmd/gc/range.c
+++ b/src/cmd/gc/range.c
@@ -182,8 +182,8 @@ walkrange(Node *n)
th = typ(TARRAY);
th->type = ptrto(types[TUINT8]);
// see ../../pkg/runtime/hashmap.h:/hash_iter
- // Size in words.
- th->bound = 5 + 4*3 + 4*4/widthptr;
+ // Size of hash_iter in # of pointers.
+ th->bound = 10;
hit = temp(th);
fn = syslook("mapiterinit", 1);
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index b8eb79938..8b546e235 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -1026,10 +1026,23 @@ dalgsym(Type *t)
}
static int
+gcinline(Type *t) {
+ switch(t->etype) {
+ case TARRAY:
+ if(t->bound == 1)
+ return 1;
+ if(t->width <= 4*widthptr)
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+static int
dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
{
Type *t1;
- vlong o, off2, fieldoffset;
+ vlong o, off2, fieldoffset, i;
if(t->align > 0 && (*off % t->align) != 0)
fatal("dgcsym1: invalid initial alignment, %T", t);
@@ -1069,7 +1082,6 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
*off += t->width;
break;
- case TCHAN:
case TUNSAFEPTR:
case TFUNC:
if(*off % widthptr != 0)
@@ -1079,6 +1091,16 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
*off += t->width;
break;
+ // struct Hchan*
+ case TCHAN:
+ if(*off % widthptr != 0)
+ fatal("dgcsym1: invalid alignment, %T", t);
+ ot = duintptr(s, ot, GC_CHAN_PTR);
+ ot = duintptr(s, ot, *off);
+ ot = dsymptr(s, ot, dtypesym(t), 0);
+ *off += t->width;
+ break;
+
// struct Hmap*
case TMAP:
if(*off % widthptr != 0)
@@ -1132,8 +1154,9 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
} else {
if(t->bound < 1 || !haspointers(t->type)) {
*off += t->width;
- } else if(t->bound == 1) {
- ot = dgcsym1(s, ot, t->type, off, stack_size); // recursive call of dgcsym1
+ } else if(gcinline(t)) {
+ for(i=0; i<t->bound; i++)
+ ot = dgcsym1(s, ot, t->type, off, stack_size); // recursive call of dgcsym1
} else {
if(stack_size < GC_STACK_CAPACITY) {
ot = duintptr(s, ot, GC_ARRAY_START); // a stack push during GC
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index c53eaf285..796851f1a 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -2565,6 +2565,7 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
fn->dupok = 1;
typecheck(&fn, Etop);
typechecklist(fn->nbody, Etop);
+ inlcalls(fn);
curfn = nil;
funccompile(fn, 0);
}
@@ -3722,3 +3723,17 @@ isbadimport(Strlit *path)
}
return 0;
}
+
+void
+checknotnil(Node *x, NodeList **init)
+{
+ Node *n;
+
+ if(isinter(x->type)) {
+ x = nod(OITAB, x, N);
+ typecheck(&x, Erv);
+ }
+ n = nod(OCHECKNOTNIL, x, N);
+ n->typecheck = 1;
+ *init = list(*init, n);
+}
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index a497b8622..5fba73140 100644
--- a/src/cmd/gc/swt.c
+++ b/src/cmd/gc/swt.c
@@ -322,6 +322,10 @@ casebody(Node *sw, Node *typeswvar)
setlineno(last);
yyerror("cannot fallthrough in type switch");
}
+ if(l->next == nil) {
+ setlineno(last);
+ yyerror("cannot fallthrough final case in switch");
+ }
last->op = OFALL;
} else
stat = list(stat, br);
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index fbab85d03..938716e21 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -276,6 +276,29 @@ callrecvlist(NodeList *l)
return 0;
}
+// indexlit implements typechecking of untyped values as
+// array/slice indexes. It is equivalent to defaultlit
+// except for constants of numerical kind, which are acceptable
+// whenever they can be represented by a value of type int.
+static void
+indexlit(Node **np)
+{
+ Node *n;
+
+ n = *np;
+ if(n == N || !isideal(n->type))
+ return;
+ switch(consttype(n)) {
+ case CTINT:
+ case CTRUNE:
+ case CTFLT:
+ case CTCPLX:
+ defaultlit(np, types[TINT]);
+ break;
+ }
+ defaultlit(np, T);
+}
+
static void
typecheck1(Node **np, int top)
{
@@ -732,6 +755,7 @@ reswitch:
yyerror("rhs of . must be a name"); // impossible
goto error;
}
+ r = n->right;
if(n->left->op == OTYPE) {
if(!looktypedot(n, t, 0)) {
@@ -775,7 +799,12 @@ reswitch:
switch(n->op) {
case ODOTINTER:
case ODOTMETH:
- ok |= Ecall;
+ if(top&Ecall)
+ ok |= Ecall;
+ else {
+ typecheckpartialcall(n, r);
+ ok |= Erv;
+ }
break;
default:
ok |= Erv;
@@ -839,7 +868,7 @@ reswitch:
case TSTRING:
case TARRAY:
- defaultlit(&n->right, T);
+ indexlit(&n->right);
if(t->etype == TSTRING)
n->type = types[TUINT8];
else
@@ -855,8 +884,8 @@ reswitch:
yyerror("non-integer %s index %N", why, n->right);
break;
}
- if(n->right->op == OLITERAL) {
- if(mpgetfix(n->right->val.u.xval) < 0)
+ if(isconst(n->right, CTINT)) {
+ if(mpgetfix(n->right->val.u.xval) < 0)
yyerror("invalid %s index %N (index must be non-negative)", why, n->right);
else if(isfixedarray(t) && t->bound > 0 && mpgetfix(n->right->val.u.xval) >= t->bound)
yyerror("invalid array index %N (out of bounds for %d-element array)", n->right, t->bound);
@@ -932,8 +961,8 @@ reswitch:
typecheck(&n->right->left, Erv);
typecheck(&n->right->right, Erv);
defaultlit(&n->left, T);
- defaultlit(&n->right->left, T);
- defaultlit(&n->right->right, T);
+ indexlit(&n->right->left);
+ indexlit(&n->right->right);
l = n->left;
if(isfixedarray(l->type)) {
if(!islvalue(n->left)) {
@@ -1180,16 +1209,18 @@ reswitch:
if(l->type == T || r->type == T)
goto error;
defaultlit2(&l, &r, 0);
+ if(l->type == T || r->type == T)
+ goto error;
n->left = l;
n->right = r;
- if(l->type->etype != r->type->etype) {
- badcmplx:
- yyerror("invalid operation: %N (complex of types %T, %T)", n, l->type, r->type);
+ if(!eqtype(l->type, r->type)) {
+ yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
goto error;
}
switch(l->type->etype) {
default:
- goto badcmplx;
+ yyerror("invalid operation: %N (arguments have type %T, expected floating-point)", n, l->type, r->type);
+ goto error;
case TIDEAL:
t = types[TIDEAL];
break;
@@ -1692,10 +1723,6 @@ ret:
yyerror("%N is not a type", n);
goto error;
}
- if((ok & Ecall) && !(top & Ecall)) {
- yyerror("method %N is not an expression, must be called", n);
- goto error;
- }
// TODO(rsc): simplify
if((top & (Ecall|Erv|Etype)) && !(top & Etop) && !(ok & (Erv|Etype|Ecall))) {
yyerror("%N used as value", n);
@@ -2558,6 +2585,7 @@ islvalue(Node *n)
// fall through
case OIND:
case ODOTPTR:
+ case OCLOSUREVAR:
return 1;
case ODOT:
return islvalue(n->left);
@@ -3144,3 +3172,148 @@ checkmake(Type *t, char *arg, Node *n)
}
return 0;
}
+
+static void markbreaklist(NodeList*, Node*);
+
+static void
+markbreak(Node *n, Node *implicit)
+{
+ Label *lab;
+
+ if(n == N)
+ return;
+
+ switch(n->op) {
+ case OBREAK:
+ if(n->left == N) {
+ if(implicit)
+ implicit->hasbreak = 1;
+ } else {
+ lab = n->left->sym->label;
+ if(lab != L)
+ lab->def->hasbreak = 1;
+ }
+ break;
+
+ case OFOR:
+ case OSWITCH:
+ case OTYPESW:
+ case OSELECT:
+ case ORANGE:
+ implicit = n;
+ // fall through
+
+ default:
+ markbreak(n->left, implicit);
+ markbreak(n->right, implicit);
+ markbreak(n->ntest, implicit);
+ markbreak(n->nincr, implicit);
+ markbreaklist(n->ninit, implicit);
+ markbreaklist(n->nbody, implicit);
+ markbreaklist(n->nelse, implicit);
+ markbreaklist(n->list, implicit);
+ markbreaklist(n->rlist, implicit);
+ break;
+ }
+}
+
+static void
+markbreaklist(NodeList *l, Node *implicit)
+{
+ Node *n;
+ Label *lab;
+
+ for(; l; l=l->next) {
+ n = l->n;
+ if(n->op == OLABEL && l->next && n->defn == l->next->n) {
+ switch(n->defn->op) {
+ case OFOR:
+ case OSWITCH:
+ case OTYPESW:
+ case OSELECT:
+ case ORANGE:
+ lab = mal(sizeof *lab);
+ lab->def = n->defn;
+ n->left->sym->label = lab;
+ markbreak(n->defn, n->defn);
+ n->left->sym->label = L;
+ l = l->next;
+ continue;
+ }
+ }
+ markbreak(n, implicit);
+ }
+}
+
+static int
+isterminating(NodeList *l, int top)
+{
+ int def;
+ Node *n;
+
+ if(l == nil)
+ return 0;
+ if(top) {
+ while(l->next && l->n->op != OLABEL)
+ l = l->next;
+ markbreaklist(l, nil);
+ }
+ while(l->next)
+ l = l->next;
+ n = l->n;
+
+ if(n == N)
+ return 0;
+
+ switch(n->op) {
+ // NOTE: OLABEL is treated as a separate statement,
+ // not a separate prefix, so skipping to the last statement
+ // in the block handles the labeled statement case by
+ // skipping over the label. No case OLABEL here.
+
+ case OBLOCK:
+ return isterminating(n->list, 0);
+
+ case OGOTO:
+ case ORETURN:
+ case OPANIC:
+ case OXFALL:
+ return 1;
+
+ case OFOR:
+ if(n->ntest != N)
+ return 0;
+ if(n->hasbreak)
+ return 0;
+ return 1;
+
+ case OIF:
+ return isterminating(n->nbody, 0) && isterminating(n->nelse, 0);
+
+ case OSWITCH:
+ case OTYPESW:
+ case OSELECT:
+ if(n->hasbreak)
+ return 0;
+ def = 0;
+ for(l=n->list; l; l=l->next) {
+ if(!isterminating(l->n->nbody, 0))
+ return 0;
+ if(l->n->list == nil) // default
+ def = 1;
+ }
+ if(n->op != OSELECT && !def)
+ return 0;
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+checkreturn(Node *fn)
+{
+ if(fn->type->outtuple && fn->nbody != nil)
+ if(!isterminating(fn->nbody, 1))
+ yyerrorl(fn->endlineno, "missing return at end of function");
+}
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index de2105ed3..50e05fc3c 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -29,40 +29,6 @@ static void walkdiv(Node**, NodeList**);
static int bounded(Node*, int64);
static Mpint mpzero;
-// can this code branch reach the end
-// without an unconditional RETURN
-// this is hard, so it is conservative
-static int
-walkret(NodeList *l)
-{
- Node *n;
-
-loop:
- while(l && l->next)
- l = l->next;
- if(l == nil)
- return 1;
-
- // at this point, we have the last
- // statement of the function
- n = l->n;
- switch(n->op) {
- case OBLOCK:
- l = n->list;
- goto loop;
-
- case OGOTO:
- case ORETURN:
- case OPANIC:
- return 0;
- break;
- }
-
- // all other statements
- // will flow to the end
- return 1;
-}
-
void
walk(Node *fn)
{
@@ -76,9 +42,6 @@ walk(Node *fn)
snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
dumplist(s, curfn->nbody);
}
- if(curfn->type->outtuple)
- if(walkret(curfn->nbody))
- yyerror("function ends without a return statement");
lno = lineno;
@@ -221,6 +184,7 @@ walkstmt(Node **np)
case OLABEL:
case ODCLCONST:
case ODCLTYPE:
+ case OCHECKNOTNIL:
break;
case OBLOCK:
@@ -433,13 +397,28 @@ walkexpr(Node **np, NodeList **init)
case OIMAG:
case ODOTMETH:
case ODOTINTER:
+ walkexpr(&n->left, init);
+ goto ret;
+
case OIND:
+ if(n->left->type->type->width == 0) {
+ n->left = cheapexpr(n->left, init);
+ checknotnil(n->left, init);
+ }
walkexpr(&n->left, init);
goto ret;
case ODOT:
+ usefield(n);
+ walkexpr(&n->left, init);
+ goto ret;
+
case ODOTPTR:
usefield(n);
+ if(n->op == ODOTPTR && n->left->type->type->width == 0) {
+ n->left = cheapexpr(n->left, init);
+ checknotnil(n->left, init);
+ }
walkexpr(&n->left, init);
goto ret;
@@ -561,13 +540,6 @@ walkexpr(Node **np, NodeList **init)
if(n->list && n->list->n->op == OAS)
goto ret;
- /*
- if(n->left->op == OCLOSURE) {
- walkcallclosure(n, init);
- t = n->left->type;
- }
- */
-
walkexpr(&n->left, init);
walkexprlist(n->list, init);
@@ -673,8 +645,48 @@ walkexpr(Node **np, NodeList **init)
r = n->rlist->n;
walkexprlistsafe(n->list, init);
walkexpr(&r->left, init);
- fn = mapfn("mapaccess2", r->left->type);
- r = mkcall1(fn, getoutargx(fn->type), init, typename(r->left->type), r->left, r->right);
+ t = r->left->type;
+ p = nil;
+ if(t->type->width <= 128) { // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing.
+ switch(simsimtype(t->down)) {
+ case TINT32:
+ case TUINT32:
+ p = "mapaccess2_fast32";
+ break;
+ case TINT64:
+ case TUINT64:
+ p = "mapaccess2_fast64";
+ break;
+ case TSTRING:
+ p = "mapaccess2_faststr";
+ break;
+ }
+ }
+ if(p != nil) {
+ // from:
+ // a,b = m[i]
+ // to:
+ // var,b = mapaccess2_fast*(t, m, i)
+ // a = *var
+ a = n->list->n;
+ var = temp(ptrto(t->type));
+ var->typecheck = 1;
+
+ fn = mapfn(p, t);
+ r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right);
+ n->rlist = list1(r);
+ n->op = OAS2FUNC;
+ n->list->n = var;
+ walkexpr(&n, init);
+ *init = list(*init, n);
+
+ n = nod(OAS, a, nod(OIND, var, N));
+ typecheck(&n, Etop);
+ walkexpr(&n, init);
+ goto ret;
+ }
+ fn = mapfn("mapaccess2", t);
+ r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right);
n->rlist = list1(r);
n->op = OAS2FUNC;
goto as2func;
@@ -1041,7 +1053,33 @@ walkexpr(Node **np, NodeList **init)
goto ret;
t = n->left->type;
- n = mkcall1(mapfn("mapaccess1", t), t->type, init, typename(t), n->left, n->right);
+ p = nil;
+ if(t->type->width <= 128) { // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing.
+ switch(simsimtype(t->down)) {
+ case TINT32:
+ case TUINT32:
+ p = "mapaccess1_fast32";
+ break;
+ case TINT64:
+ case TUINT64:
+ p = "mapaccess1_fast64";
+ break;
+ case TSTRING:
+ p = "mapaccess1_faststr";
+ break;
+ }
+ }
+ if(p != nil) {
+ // use fast version. The fast versions return a pointer to the value - we need
+ // to dereference it to get the result.
+ n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, n->right);
+ n = nod(OIND, n, N);
+ n->type = t->type;
+ n->typecheck = 1;
+ } else {
+ // no fast version for this key
+ n = mkcall1(mapfn("mapaccess1", t), t->type, init, typename(t), n->left, n->right);
+ }
goto ret;
case ORECV:
@@ -1292,6 +1330,10 @@ walkexpr(Node **np, NodeList **init)
case OCLOSURE:
n = walkclosure(n, init);
goto ret;
+
+ case OCALLPART:
+ n = walkpartialcall(n, init);
+ goto ret;
}
fatal("missing switch %O", n->op);
diff --git a/src/cmd/gc/y.tab.c b/src/cmd/gc/y.tab.c
index 75175455e..dee793998 100644
--- a/src/cmd/gc/y.tab.c
+++ b/src/cmd/gc/y.tab.c
@@ -662,35 +662,35 @@ static const yytype_uint16 yyrline[] =
304, 308, 312, 318, 324, 330, 335, 339, 343, 349,
355, 359, 363, 369, 373, 379, 380, 384, 390, 399,
405, 423, 428, 440, 456, 461, 468, 488, 506, 515,
- 534, 533, 545, 544, 575, 578, 585, 584, 595, 601,
- 610, 621, 627, 630, 638, 637, 648, 654, 666, 670,
- 675, 665, 696, 695, 708, 711, 717, 720, 732, 736,
- 731, 754, 753, 769, 770, 774, 778, 782, 786, 790,
- 794, 798, 802, 806, 810, 814, 818, 822, 826, 830,
- 834, 838, 842, 847, 853, 854, 858, 869, 873, 877,
- 881, 886, 890, 900, 904, 909, 917, 921, 922, 933,
- 937, 941, 945, 949, 950, 956, 963, 969, 976, 979,
- 986, 992, 1009, 1016, 1017, 1024, 1025, 1044, 1045, 1048,
- 1051, 1055, 1066, 1075, 1081, 1084, 1087, 1094, 1095, 1101,
- 1116, 1124, 1136, 1141, 1147, 1148, 1149, 1150, 1151, 1152,
- 1158, 1159, 1160, 1161, 1167, 1168, 1169, 1170, 1171, 1177,
- 1178, 1181, 1184, 1185, 1186, 1187, 1188, 1191, 1192, 1205,
- 1209, 1214, 1219, 1224, 1228, 1229, 1232, 1238, 1245, 1251,
- 1258, 1264, 1275, 1289, 1318, 1358, 1383, 1401, 1410, 1413,
- 1421, 1425, 1429, 1436, 1442, 1447, 1459, 1462, 1472, 1473,
- 1479, 1480, 1486, 1490, 1496, 1497, 1503, 1507, 1513, 1536,
- 1541, 1547, 1553, 1560, 1569, 1578, 1593, 1599, 1604, 1608,
- 1615, 1628, 1629, 1635, 1641, 1644, 1648, 1654, 1657, 1666,
- 1669, 1670, 1674, 1675, 1681, 1682, 1683, 1684, 1685, 1687,
- 1686, 1701, 1706, 1710, 1714, 1718, 1722, 1727, 1746, 1752,
- 1760, 1764, 1770, 1774, 1780, 1784, 1790, 1794, 1803, 1807,
- 1811, 1815, 1821, 1824, 1832, 1833, 1835, 1836, 1839, 1842,
- 1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872,
- 1875, 1878, 1884, 1888, 1892, 1896, 1900, 1904, 1924, 1931,
- 1942, 1943, 1944, 1947, 1948, 1951, 1955, 1965, 1969, 1973,
- 1977, 1981, 1985, 1989, 1995, 2001, 2009, 2017, 2023, 2030,
- 2046, 2064, 2068, 2074, 2077, 2080, 2084, 2094, 2098, 2113,
- 2121, 2122, 2134, 2135, 2138, 2142, 2148, 2152, 2158, 2162
+ 534, 533, 548, 547, 578, 581, 588, 587, 598, 604,
+ 613, 624, 630, 633, 641, 640, 651, 657, 669, 673,
+ 678, 668, 699, 698, 711, 714, 720, 723, 735, 739,
+ 734, 757, 756, 772, 773, 777, 781, 785, 789, 793,
+ 797, 801, 805, 809, 813, 817, 821, 825, 829, 833,
+ 837, 841, 845, 850, 856, 857, 861, 872, 876, 880,
+ 884, 889, 893, 903, 907, 912, 920, 924, 925, 936,
+ 940, 944, 948, 952, 953, 959, 966, 972, 979, 982,
+ 989, 995, 1012, 1019, 1020, 1027, 1028, 1047, 1048, 1051,
+ 1054, 1058, 1069, 1078, 1084, 1087, 1090, 1097, 1098, 1104,
+ 1119, 1127, 1139, 1144, 1150, 1151, 1152, 1153, 1154, 1155,
+ 1161, 1162, 1163, 1164, 1170, 1171, 1172, 1173, 1174, 1180,
+ 1181, 1184, 1187, 1188, 1189, 1190, 1191, 1194, 1195, 1208,
+ 1212, 1217, 1222, 1227, 1231, 1232, 1235, 1241, 1248, 1254,
+ 1261, 1267, 1278, 1292, 1321, 1361, 1386, 1404, 1413, 1416,
+ 1424, 1428, 1432, 1439, 1445, 1450, 1462, 1465, 1475, 1476,
+ 1482, 1483, 1489, 1493, 1499, 1500, 1506, 1510, 1516, 1539,
+ 1544, 1550, 1556, 1563, 1572, 1581, 1596, 1602, 1607, 1611,
+ 1618, 1631, 1632, 1638, 1644, 1647, 1651, 1657, 1660, 1669,
+ 1672, 1673, 1677, 1678, 1684, 1685, 1686, 1687, 1688, 1690,
+ 1689, 1704, 1709, 1713, 1717, 1721, 1725, 1730, 1749, 1755,
+ 1763, 1767, 1773, 1777, 1783, 1787, 1793, 1797, 1806, 1810,
+ 1814, 1818, 1824, 1827, 1835, 1836, 1838, 1839, 1842, 1845,
+ 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872, 1875,
+ 1878, 1881, 1887, 1891, 1895, 1899, 1903, 1907, 1927, 1934,
+ 1945, 1946, 1947, 1950, 1951, 1954, 1958, 1968, 1972, 1976,
+ 1980, 1984, 1988, 1992, 1998, 2004, 2012, 2020, 2026, 2033,
+ 2049, 2067, 2071, 2077, 2080, 2083, 2087, 2097, 2101, 2116,
+ 2124, 2125, 2137, 2138, 2141, 2145, 2151, 2155, 2161, 2165
};
#endif
@@ -2867,13 +2867,16 @@ yyreduce:
case 61:
#line 538 "go.y"
{
- (yyval.node) = liststmt((yyvsp[(3) - (4)].list));
+ if((yyvsp[(3) - (4)].list) == nil)
+ (yyval.node) = nod(OEMPTY, N, N);
+ else
+ (yyval.node) = liststmt((yyvsp[(3) - (4)].list));
popdcl();
}
break;
case 62:
-#line 545 "go.y"
+#line 548 "go.y"
{
// If the last token read by the lexer was consumed
// as part of the case, clear it (parser has cleared yychar).
@@ -2886,7 +2889,7 @@ yyreduce:
break;
case 63:
-#line 555 "go.y"
+#line 558 "go.y"
{
int last;
@@ -2908,28 +2911,28 @@ yyreduce:
break;
case 64:
-#line 575 "go.y"
+#line 578 "go.y"
{
(yyval.list) = nil;
}
break;
case 65:
-#line 579 "go.y"
+#line 582 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
}
break;
case 66:
-#line 585 "go.y"
+#line 588 "go.y"
{
markdcl();
}
break;
case 67:
-#line 589 "go.y"
+#line 592 "go.y"
{
(yyval.list) = (yyvsp[(3) - (4)].list);
popdcl();
@@ -2937,7 +2940,7 @@ yyreduce:
break;
case 68:
-#line 596 "go.y"
+#line 599 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -2946,7 +2949,7 @@ yyreduce:
break;
case 69:
-#line 602 "go.y"
+#line 605 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -2956,7 +2959,7 @@ yyreduce:
break;
case 70:
-#line 611 "go.y"
+#line 614 "go.y"
{
// init ; test ; incr
if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0)
@@ -2970,7 +2973,7 @@ yyreduce:
break;
case 71:
-#line 622 "go.y"
+#line 625 "go.y"
{
// normal test
(yyval.node) = nod(OFOR, N, N);
@@ -2979,7 +2982,7 @@ yyreduce:
break;
case 73:
-#line 631 "go.y"
+#line 634 "go.y"
{
(yyval.node) = (yyvsp[(1) - (2)].node);
(yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list));
@@ -2987,14 +2990,14 @@ yyreduce:
break;
case 74:
-#line 638 "go.y"
+#line 641 "go.y"
{
markdcl();
}
break;
case 75:
-#line 642 "go.y"
+#line 645 "go.y"
{
(yyval.node) = (yyvsp[(3) - (3)].node);
popdcl();
@@ -3002,7 +3005,7 @@ yyreduce:
break;
case 76:
-#line 649 "go.y"
+#line 652 "go.y"
{
// test
(yyval.node) = nod(OIF, N, N);
@@ -3011,7 +3014,7 @@ yyreduce:
break;
case 77:
-#line 655 "go.y"
+#line 658 "go.y"
{
// init ; test
(yyval.node) = nod(OIF, N, N);
@@ -3022,14 +3025,14 @@ yyreduce:
break;
case 78:
-#line 666 "go.y"
+#line 669 "go.y"
{
markdcl();
}
break;
case 79:
-#line 670 "go.y"
+#line 673 "go.y"
{
if((yyvsp[(3) - (3)].node)->ntest == N)
yyerror("missing condition in if statement");
@@ -3037,14 +3040,14 @@ yyreduce:
break;
case 80:
-#line 675 "go.y"
+#line 678 "go.y"
{
(yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
}
break;
case 81:
-#line 679 "go.y"
+#line 682 "go.y"
{
Node *n;
NodeList *nn;
@@ -3062,14 +3065,14 @@ yyreduce:
break;
case 82:
-#line 696 "go.y"
+#line 699 "go.y"
{
markdcl();
}
break;
case 83:
-#line 700 "go.y"
+#line 703 "go.y"
{
if((yyvsp[(4) - (5)].node)->ntest == N)
yyerror("missing condition in if statement");
@@ -3079,28 +3082,28 @@ yyreduce:
break;
case 84:
-#line 708 "go.y"
+#line 711 "go.y"
{
(yyval.list) = nil;
}
break;
case 85:
-#line 712 "go.y"
+#line 715 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list));
}
break;
case 86:
-#line 717 "go.y"
+#line 720 "go.y"
{
(yyval.list) = nil;
}
break;
case 87:
-#line 721 "go.y"
+#line 724 "go.y"
{
NodeList *node;
@@ -3112,14 +3115,14 @@ yyreduce:
break;
case 88:
-#line 732 "go.y"
+#line 735 "go.y"
{
markdcl();
}
break;
case 89:
-#line 736 "go.y"
+#line 739 "go.y"
{
Node *n;
n = (yyvsp[(3) - (3)].node)->ntest;
@@ -3130,7 +3133,7 @@ yyreduce:
break;
case 90:
-#line 744 "go.y"
+#line 747 "go.y"
{
(yyval.node) = (yyvsp[(3) - (7)].node);
(yyval.node)->op = OSWITCH;
@@ -3141,14 +3144,14 @@ yyreduce:
break;
case 91:
-#line 754 "go.y"
+#line 757 "go.y"
{
typesw = nod(OXXX, typesw, N);
}
break;
case 92:
-#line 758 "go.y"
+#line 761 "go.y"
{
(yyval.node) = nod(OSELECT, N, N);
(yyval.node)->lineno = typesw->lineno;
@@ -3158,154 +3161,154 @@ yyreduce:
break;
case 94:
-#line 771 "go.y"
+#line 774 "go.y"
{
(yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 95:
-#line 775 "go.y"
+#line 778 "go.y"
{
(yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 96:
-#line 779 "go.y"
+#line 782 "go.y"
{
(yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 97:
-#line 783 "go.y"
+#line 786 "go.y"
{
(yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 98:
-#line 787 "go.y"
+#line 790 "go.y"
{
(yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 99:
-#line 791 "go.y"
+#line 794 "go.y"
{
(yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 100:
-#line 795 "go.y"
+#line 798 "go.y"
{
(yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 101:
-#line 799 "go.y"
+#line 802 "go.y"
{
(yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 102:
-#line 803 "go.y"
+#line 806 "go.y"
{
(yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 103:
-#line 807 "go.y"
+#line 810 "go.y"
{
(yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 104:
-#line 811 "go.y"
+#line 814 "go.y"
{
(yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 105:
-#line 815 "go.y"
+#line 818 "go.y"
{
(yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 106:
-#line 819 "go.y"
+#line 822 "go.y"
{
(yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 107:
-#line 823 "go.y"
+#line 826 "go.y"
{
(yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 108:
-#line 827 "go.y"
+#line 830 "go.y"
{
(yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 109:
-#line 831 "go.y"
+#line 834 "go.y"
{
(yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 110:
-#line 835 "go.y"
+#line 838 "go.y"
{
(yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 111:
-#line 839 "go.y"
+#line 842 "go.y"
{
(yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 112:
-#line 843 "go.y"
+#line 846 "go.y"
{
(yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 113:
-#line 848 "go.y"
+#line 851 "go.y"
{
(yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 115:
-#line 855 "go.y"
+#line 858 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 116:
-#line 859 "go.y"
+#line 862 "go.y"
{
if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) {
// Special case for &T{...}: turn into (*T){...}.
@@ -3319,28 +3322,28 @@ yyreduce:
break;
case 117:
-#line 870 "go.y"
+#line 873 "go.y"
{
(yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N);
}
break;
case 118:
-#line 874 "go.y"
+#line 877 "go.y"
{
(yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N);
}
break;
case 119:
-#line 878 "go.y"
+#line 881 "go.y"
{
(yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N);
}
break;
case 120:
-#line 882 "go.y"
+#line 885 "go.y"
{
yyerror("the bitwise complement operator is ^");
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
@@ -3348,28 +3351,28 @@ yyreduce:
break;
case 121:
-#line 887 "go.y"
+#line 890 "go.y"
{
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
}
break;
case 122:
-#line 891 "go.y"
+#line 894 "go.y"
{
(yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N);
}
break;
case 123:
-#line 901 "go.y"
+#line 904 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N);
}
break;
case 124:
-#line 905 "go.y"
+#line 908 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3377,7 +3380,7 @@ yyreduce:
break;
case 125:
-#line 910 "go.y"
+#line 913 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N);
(yyval.node)->list = (yyvsp[(3) - (6)].list);
@@ -3386,14 +3389,14 @@ yyreduce:
break;
case 126:
-#line 918 "go.y"
+#line 921 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
case 128:
-#line 923 "go.y"
+#line 926 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
@@ -3407,35 +3410,35 @@ yyreduce:
break;
case 129:
-#line 934 "go.y"
+#line 937 "go.y"
{
(yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node));
}
break;
case 130:
-#line 938 "go.y"
+#line 941 "go.y"
{
(yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node));
}
break;
case 131:
-#line 942 "go.y"
+#line 945 "go.y"
{
(yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
}
break;
case 132:
-#line 946 "go.y"
+#line 949 "go.y"
{
(yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node)));
}
break;
case 134:
-#line 951 "go.y"
+#line 954 "go.y"
{
// conversion
(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
@@ -3444,7 +3447,7 @@ yyreduce:
break;
case 135:
-#line 957 "go.y"
+#line 960 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3454,7 +3457,7 @@ yyreduce:
break;
case 136:
-#line 964 "go.y"
+#line 967 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3463,7 +3466,7 @@ yyreduce:
break;
case 137:
-#line 970 "go.y"
+#line 973 "go.y"
{
yyerror("cannot parenthesize type in composite literal");
(yyval.node) = (yyvsp[(5) - (7)].node);
@@ -3473,7 +3476,7 @@ yyreduce:
break;
case 139:
-#line 979 "go.y"
+#line 982 "go.y"
{
// composite expression.
// make node early so we get the right line number.
@@ -3482,14 +3485,14 @@ yyreduce:
break;
case 140:
-#line 987 "go.y"
+#line 990 "go.y"
{
(yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 141:
-#line 993 "go.y"
+#line 996 "go.y"
{
// These nodes do not carry line numbers.
// Since a composite literal commonly spans several lines,
@@ -3509,7 +3512,7 @@ yyreduce:
break;
case 142:
-#line 1010 "go.y"
+#line 1013 "go.y"
{
(yyval.node) = (yyvsp[(2) - (4)].node);
(yyval.node)->list = (yyvsp[(3) - (4)].list);
@@ -3517,7 +3520,7 @@ yyreduce:
break;
case 144:
-#line 1018 "go.y"
+#line 1021 "go.y"
{
(yyval.node) = (yyvsp[(2) - (4)].node);
(yyval.node)->list = (yyvsp[(3) - (4)].list);
@@ -3525,7 +3528,7 @@ yyreduce:
break;
case 146:
-#line 1026 "go.y"
+#line 1029 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
@@ -3545,21 +3548,21 @@ yyreduce:
break;
case 150:
-#line 1052 "go.y"
+#line 1055 "go.y"
{
(yyval.i) = LBODY;
}
break;
case 151:
-#line 1056 "go.y"
+#line 1059 "go.y"
{
(yyval.i) = '{';
}
break;
case 152:
-#line 1067 "go.y"
+#line 1070 "go.y"
{
if((yyvsp[(1) - (1)].sym) == S)
(yyval.node) = N;
@@ -3569,21 +3572,21 @@ yyreduce:
break;
case 153:
-#line 1076 "go.y"
+#line 1079 "go.y"
{
(yyval.node) = dclname((yyvsp[(1) - (1)].sym));
}
break;
case 154:
-#line 1081 "go.y"
+#line 1084 "go.y"
{
(yyval.node) = N;
}
break;
case 156:
-#line 1088 "go.y"
+#line 1091 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
// during imports, unqualified non-exported identifiers are from builtinpkg
@@ -3593,14 +3596,14 @@ yyreduce:
break;
case 158:
-#line 1096 "go.y"
+#line 1099 "go.y"
{
(yyval.sym) = S;
}
break;
case 159:
-#line 1102 "go.y"
+#line 1105 "go.y"
{
Pkg *p;
@@ -3616,7 +3619,7 @@ yyreduce:
break;
case 160:
-#line 1117 "go.y"
+#line 1120 "go.y"
{
(yyval.node) = oldname((yyvsp[(1) - (1)].sym));
if((yyval.node)->pack != N)
@@ -3625,7 +3628,7 @@ yyreduce:
break;
case 162:
-#line 1137 "go.y"
+#line 1140 "go.y"
{
yyerror("final argument in variadic function missing type");
(yyval.node) = nod(ODDD, typenod(typ(TINTER)), N);
@@ -3633,35 +3636,35 @@ yyreduce:
break;
case 163:
-#line 1142 "go.y"
+#line 1145 "go.y"
{
(yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N);
}
break;
case 169:
-#line 1153 "go.y"
+#line 1156 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
case 173:
-#line 1162 "go.y"
+#line 1165 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 178:
-#line 1172 "go.y"
+#line 1175 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
case 188:
-#line 1193 "go.y"
+#line 1196 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
@@ -3675,14 +3678,14 @@ yyreduce:
break;
case 189:
-#line 1206 "go.y"
+#line 1209 "go.y"
{
(yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node));
}
break;
case 190:
-#line 1210 "go.y"
+#line 1213 "go.y"
{
// array literal of nelem
(yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node));
@@ -3690,7 +3693,7 @@ yyreduce:
break;
case 191:
-#line 1215 "go.y"
+#line 1218 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N);
(yyval.node)->etype = Cboth;
@@ -3698,7 +3701,7 @@ yyreduce:
break;
case 192:
-#line 1220 "go.y"
+#line 1223 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Csend;
@@ -3706,21 +3709,21 @@ yyreduce:
break;
case 193:
-#line 1225 "go.y"
+#line 1228 "go.y"
{
(yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
}
break;
case 196:
-#line 1233 "go.y"
+#line 1236 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 197:
-#line 1239 "go.y"
+#line 1242 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Crecv;
@@ -3728,7 +3731,7 @@ yyreduce:
break;
case 198:
-#line 1246 "go.y"
+#line 1249 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3737,7 +3740,7 @@ yyreduce:
break;
case 199:
-#line 1252 "go.y"
+#line 1255 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
@@ -3745,7 +3748,7 @@ yyreduce:
break;
case 200:
-#line 1259 "go.y"
+#line 1262 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3754,7 +3757,7 @@ yyreduce:
break;
case 201:
-#line 1265 "go.y"
+#line 1268 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
@@ -3762,7 +3765,7 @@ yyreduce:
break;
case 202:
-#line 1276 "go.y"
+#line 1279 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
if((yyval.node) == N)
@@ -3777,7 +3780,7 @@ yyreduce:
break;
case 203:
-#line 1290 "go.y"
+#line 1293 "go.y"
{
Node *t;
@@ -3809,7 +3812,7 @@ yyreduce:
break;
case 204:
-#line 1319 "go.y"
+#line 1322 "go.y"
{
Node *rcvr, *t;
@@ -3850,7 +3853,7 @@ yyreduce:
break;
case 205:
-#line 1359 "go.y"
+#line 1362 "go.y"
{
Sym *s;
Type *t;
@@ -3878,7 +3881,7 @@ yyreduce:
break;
case 206:
-#line 1384 "go.y"
+#line 1387 "go.y"
{
(yyval.node) = methodname1(newname((yyvsp[(4) - (8)].sym)), (yyvsp[(2) - (8)].list)->n->right);
(yyval.node)->type = functype((yyvsp[(2) - (8)].list)->n, (yyvsp[(6) - (8)].list), (yyvsp[(8) - (8)].list));
@@ -3897,7 +3900,7 @@ yyreduce:
break;
case 207:
-#line 1402 "go.y"
+#line 1405 "go.y"
{
(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
(yyval.node) = nod(OTFUNC, N, N);
@@ -3907,14 +3910,14 @@ yyreduce:
break;
case 208:
-#line 1410 "go.y"
+#line 1413 "go.y"
{
(yyval.list) = nil;
}
break;
case 209:
-#line 1414 "go.y"
+#line 1417 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
if((yyval.list) == nil)
@@ -3923,21 +3926,21 @@ yyreduce:
break;
case 210:
-#line 1422 "go.y"
+#line 1425 "go.y"
{
(yyval.list) = nil;
}
break;
case 211:
-#line 1426 "go.y"
+#line 1429 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
}
break;
case 212:
-#line 1430 "go.y"
+#line 1433 "go.y"
{
(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
(yyval.list) = (yyvsp[(2) - (3)].list);
@@ -3945,14 +3948,14 @@ yyreduce:
break;
case 213:
-#line 1437 "go.y"
+#line 1440 "go.y"
{
closurehdr((yyvsp[(1) - (1)].node));
}
break;
case 214:
-#line 1443 "go.y"
+#line 1446 "go.y"
{
(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
fixlbrace((yyvsp[(2) - (4)].i));
@@ -3960,21 +3963,21 @@ yyreduce:
break;
case 215:
-#line 1448 "go.y"
+#line 1451 "go.y"
{
(yyval.node) = closurebody(nil);
}
break;
case 216:
-#line 1459 "go.y"
+#line 1462 "go.y"
{
(yyval.list) = nil;
}
break;
case 217:
-#line 1463 "go.y"
+#line 1466 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
if(nsyntaxerrors == 0)
@@ -3985,56 +3988,56 @@ yyreduce:
break;
case 219:
-#line 1474 "go.y"
+#line 1477 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 221:
-#line 1481 "go.y"
+#line 1484 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 222:
-#line 1487 "go.y"
+#line 1490 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 223:
-#line 1491 "go.y"
+#line 1494 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 225:
-#line 1498 "go.y"
+#line 1501 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 226:
-#line 1504 "go.y"
+#line 1507 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 227:
-#line 1508 "go.y"
+#line 1511 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 228:
-#line 1514 "go.y"
+#line 1517 "go.y"
{
NodeList *l;
@@ -4060,7 +4063,7 @@ yyreduce:
break;
case 229:
-#line 1537 "go.y"
+#line 1540 "go.y"
{
(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
(yyval.list) = list1((yyvsp[(1) - (2)].node));
@@ -4068,7 +4071,7 @@ yyreduce:
break;
case 230:
-#line 1542 "go.y"
+#line 1545 "go.y"
{
(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
(yyval.list) = list1((yyvsp[(2) - (4)].node));
@@ -4077,7 +4080,7 @@ yyreduce:
break;
case 231:
-#line 1548 "go.y"
+#line 1551 "go.y"
{
(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
@@ -4086,7 +4089,7 @@ yyreduce:
break;
case 232:
-#line 1554 "go.y"
+#line 1557 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4096,7 +4099,7 @@ yyreduce:
break;
case 233:
-#line 1561 "go.y"
+#line 1564 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4106,7 +4109,7 @@ yyreduce:
break;
case 234:
-#line 1570 "go.y"
+#line 1573 "go.y"
{
Node *n;
@@ -4118,7 +4121,7 @@ yyreduce:
break;
case 235:
-#line 1579 "go.y"
+#line 1582 "go.y"
{
Pkg *pkg;
@@ -4134,14 +4137,14 @@ yyreduce:
break;
case 236:
-#line 1594 "go.y"
+#line 1597 "go.y"
{
(yyval.node) = embedded((yyvsp[(1) - (1)].sym));
}
break;
case 237:
-#line 1600 "go.y"
+#line 1603 "go.y"
{
(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
ifacedcl((yyval.node));
@@ -4149,14 +4152,14 @@ yyreduce:
break;
case 238:
-#line 1605 "go.y"
+#line 1608 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
}
break;
case 239:
-#line 1609 "go.y"
+#line 1612 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
yyerror("cannot parenthesize embedded type");
@@ -4164,7 +4167,7 @@ yyreduce:
break;
case 240:
-#line 1616 "go.y"
+#line 1619 "go.y"
{
// without func keyword
(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
@@ -4175,7 +4178,7 @@ yyreduce:
break;
case 242:
-#line 1630 "go.y"
+#line 1633 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4184,7 +4187,7 @@ yyreduce:
break;
case 243:
-#line 1636 "go.y"
+#line 1639 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4193,56 +4196,56 @@ yyreduce:
break;
case 245:
-#line 1645 "go.y"
+#line 1648 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 246:
-#line 1649 "go.y"
+#line 1652 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 247:
-#line 1654 "go.y"
+#line 1657 "go.y"
{
(yyval.list) = nil;
}
break;
case 248:
-#line 1658 "go.y"
+#line 1661 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
case 249:
-#line 1666 "go.y"
+#line 1669 "go.y"
{
(yyval.node) = N;
}
break;
case 251:
-#line 1671 "go.y"
+#line 1674 "go.y"
{
(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
}
break;
case 253:
-#line 1676 "go.y"
+#line 1679 "go.y"
{
(yyval.node) = N;
}
break;
case 259:
-#line 1687 "go.y"
+#line 1690 "go.y"
{
(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
(yyvsp[(1) - (2)].node)->sym = dclstack; // context, for goto restrictions
@@ -4250,7 +4253,7 @@ yyreduce:
break;
case 260:
-#line 1692 "go.y"
+#line 1695 "go.y"
{
NodeList *l;
@@ -4263,7 +4266,7 @@ yyreduce:
break;
case 261:
-#line 1702 "go.y"
+#line 1705 "go.y"
{
// will be converted to OFALL
(yyval.node) = nod(OXFALL, N, N);
@@ -4271,35 +4274,35 @@ yyreduce:
break;
case 262:
-#line 1707 "go.y"
+#line 1710 "go.y"
{
(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
}
break;
case 263:
-#line 1711 "go.y"
+#line 1714 "go.y"
{
(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
}
break;
case 264:
-#line 1715 "go.y"
+#line 1718 "go.y"
{
(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
}
break;
case 265:
-#line 1719 "go.y"
+#line 1722 "go.y"
{
(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
}
break;
case 266:
-#line 1723 "go.y"
+#line 1726 "go.y"
{
(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
(yyval.node)->sym = dclstack; // context, for goto restrictions
@@ -4307,7 +4310,7 @@ yyreduce:
break;
case 267:
-#line 1728 "go.y"
+#line 1731 "go.y"
{
(yyval.node) = nod(ORETURN, N, N);
(yyval.node)->list = (yyvsp[(2) - (2)].list);
@@ -4327,7 +4330,7 @@ yyreduce:
break;
case 268:
-#line 1747 "go.y"
+#line 1750 "go.y"
{
(yyval.list) = nil;
if((yyvsp[(1) - (1)].node) != N)
@@ -4336,7 +4339,7 @@ yyreduce:
break;
case 269:
-#line 1753 "go.y"
+#line 1756 "go.y"
{
(yyval.list) = (yyvsp[(1) - (3)].list);
if((yyvsp[(3) - (3)].node) != N)
@@ -4345,189 +4348,189 @@ yyreduce:
break;
case 270:
-#line 1761 "go.y"
+#line 1764 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 271:
-#line 1765 "go.y"
+#line 1768 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 272:
-#line 1771 "go.y"
+#line 1774 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 273:
-#line 1775 "go.y"
+#line 1778 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 274:
-#line 1781 "go.y"
+#line 1784 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 275:
-#line 1785 "go.y"
+#line 1788 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 276:
-#line 1791 "go.y"
+#line 1794 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 277:
-#line 1795 "go.y"
+#line 1798 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 278:
-#line 1804 "go.y"
+#line 1807 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 279:
-#line 1808 "go.y"
+#line 1811 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 280:
-#line 1812 "go.y"
+#line 1815 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 281:
-#line 1816 "go.y"
+#line 1819 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 282:
-#line 1821 "go.y"
+#line 1824 "go.y"
{
(yyval.list) = nil;
}
break;
case 283:
-#line 1825 "go.y"
+#line 1828 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
case 288:
-#line 1839 "go.y"
+#line 1842 "go.y"
{
(yyval.node) = N;
}
break;
case 290:
-#line 1845 "go.y"
+#line 1848 "go.y"
{
(yyval.list) = nil;
}
break;
case 292:
-#line 1851 "go.y"
+#line 1854 "go.y"
{
(yyval.node) = N;
}
break;
case 294:
-#line 1857 "go.y"
+#line 1860 "go.y"
{
(yyval.list) = nil;
}
break;
case 296:
-#line 1863 "go.y"
+#line 1866 "go.y"
{
(yyval.list) = nil;
}
break;
case 298:
-#line 1869 "go.y"
+#line 1872 "go.y"
{
(yyval.list) = nil;
}
break;
case 300:
-#line 1875 "go.y"
+#line 1878 "go.y"
{
(yyval.val).ctype = CTxxx;
}
break;
case 302:
-#line 1885 "go.y"
+#line 1888 "go.y"
{
importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
}
break;
case 303:
-#line 1889 "go.y"
+#line 1892 "go.y"
{
importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
}
break;
case 304:
-#line 1893 "go.y"
+#line 1896 "go.y"
{
importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
}
break;
case 305:
-#line 1897 "go.y"
+#line 1900 "go.y"
{
importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
}
break;
case 306:
-#line 1901 "go.y"
+#line 1904 "go.y"
{
importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
}
break;
case 307:
-#line 1905 "go.y"
+#line 1908 "go.y"
{
if((yyvsp[(2) - (4)].node) == N) {
dclcontext = PEXTERN; // since we skip the funcbody below
@@ -4548,7 +4551,7 @@ yyreduce:
break;
case 308:
-#line 1925 "go.y"
+#line 1928 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
structpkg = (yyval.sym)->pkg;
@@ -4556,7 +4559,7 @@ yyreduce:
break;
case 309:
-#line 1932 "go.y"
+#line 1935 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
importsym((yyvsp[(1) - (1)].sym), OTYPE);
@@ -4564,14 +4567,14 @@ yyreduce:
break;
case 315:
-#line 1952 "go.y"
+#line 1955 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
}
break;
case 316:
-#line 1956 "go.y"
+#line 1959 "go.y"
{
// predefined name like uint8
(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
@@ -4584,49 +4587,49 @@ yyreduce:
break;
case 317:
-#line 1966 "go.y"
+#line 1969 "go.y"
{
(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
}
break;
case 318:
-#line 1970 "go.y"
+#line 1973 "go.y"
{
(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
}
break;
case 319:
-#line 1974 "go.y"
+#line 1977 "go.y"
{
(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
}
break;
case 320:
-#line 1978 "go.y"
+#line 1981 "go.y"
{
(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
}
break;
case 321:
-#line 1982 "go.y"
+#line 1985 "go.y"
{
(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
}
break;
case 322:
-#line 1986 "go.y"
+#line 1989 "go.y"
{
(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
}
break;
case 323:
-#line 1990 "go.y"
+#line 1993 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(2) - (2)].type);
@@ -4635,7 +4638,7 @@ yyreduce:
break;
case 324:
-#line 1996 "go.y"
+#line 1999 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (4)].type);
@@ -4644,7 +4647,7 @@ yyreduce:
break;
case 325:
-#line 2002 "go.y"
+#line 2005 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -4653,7 +4656,7 @@ yyreduce:
break;
case 326:
-#line 2010 "go.y"
+#line 2013 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -4662,14 +4665,14 @@ yyreduce:
break;
case 327:
-#line 2018 "go.y"
+#line 2021 "go.y"
{
(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
}
break;
case 328:
-#line 2024 "go.y"
+#line 2027 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
if((yyvsp[(1) - (3)].sym))
@@ -4679,7 +4682,7 @@ yyreduce:
break;
case 329:
-#line 2031 "go.y"
+#line 2034 "go.y"
{
Type *t;
@@ -4696,7 +4699,7 @@ yyreduce:
break;
case 330:
-#line 2047 "go.y"
+#line 2050 "go.y"
{
Sym *s;
@@ -4715,49 +4718,49 @@ yyreduce:
break;
case 331:
-#line 2065 "go.y"
+#line 2068 "go.y"
{
(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list))));
}
break;
case 332:
-#line 2069 "go.y"
+#line 2072 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
}
break;
case 333:
-#line 2074 "go.y"
+#line 2077 "go.y"
{
(yyval.list) = nil;
}
break;
case 335:
-#line 2081 "go.y"
+#line 2084 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
}
break;
case 336:
-#line 2085 "go.y"
+#line 2088 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
}
break;
case 337:
-#line 2095 "go.y"
+#line 2098 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
case 338:
-#line 2099 "go.y"
+#line 2102 "go.y"
{
(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
switch((yyval.node)->val.ctype){
@@ -4775,7 +4778,7 @@ yyreduce:
break;
case 339:
-#line 2114 "go.y"
+#line 2117 "go.y"
{
(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
if((yyval.node)->op != OLITERAL)
@@ -4784,7 +4787,7 @@ yyreduce:
break;
case 341:
-#line 2123 "go.y"
+#line 2126 "go.y"
{
if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
(yyval.node) = (yyvsp[(2) - (5)].node);
@@ -4798,42 +4801,42 @@ yyreduce:
break;
case 344:
-#line 2139 "go.y"
+#line 2142 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 345:
-#line 2143 "go.y"
+#line 2146 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 346:
-#line 2149 "go.y"
+#line 2152 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 347:
-#line 2153 "go.y"
+#line 2156 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 348:
-#line 2159 "go.y"
+#line 2162 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 349:
-#line 2163 "go.y"
+#line 2166 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
@@ -4841,7 +4844,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
-#line 4846 "y.tab.c"
+#line 4849 "y.tab.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -5055,7 +5058,7 @@ yyreturn:
}
-#line 2167 "go.y"
+#line 2170 "go.y"
static void