summaryrefslogtreecommitdiff
path: root/src/cmd/gc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc')
-rw-r--r--src/cmd/gc/align.c27
-rwxr-xr-xsrc/cmd/gc/bisonerrors4
-rw-r--r--src/cmd/gc/builtin.c215
-rw-r--r--src/cmd/gc/closure.c165
-rw-r--r--src/cmd/gc/const.c359
-rw-r--r--src/cmd/gc/cplx.c4
-rw-r--r--src/cmd/gc/dcl.c136
-rw-r--r--src/cmd/gc/doc.go33
-rw-r--r--src/cmd/gc/esc.c780
-rw-r--r--src/cmd/gc/export.c96
-rw-r--r--src/cmd/gc/fmt.c127
-rw-r--r--src/cmd/gc/gen.c228
-rw-r--r--src/cmd/gc/go.errors3
-rw-r--r--src/cmd/gc/go.h343
-rw-r--r--src/cmd/gc/go.y141
-rw-r--r--src/cmd/gc/init.c4
-rw-r--r--src/cmd/gc/inl.c259
-rw-r--r--src/cmd/gc/lex.c390
-rw-r--r--src/cmd/gc/mparith1.c176
-rw-r--r--src/cmd/gc/obj.c14
-rw-r--r--src/cmd/gc/order.c6
-rw-r--r--src/cmd/gc/pgen.c50
-rw-r--r--src/cmd/gc/racewalk.c579
-rw-r--r--src/cmd/gc/range.c11
-rw-r--r--src/cmd/gc/reflect.c378
-rw-r--r--src/cmd/gc/runtime.go24
-rw-r--r--src/cmd/gc/select.c19
-rw-r--r--src/cmd/gc/sinit.c54
-rw-r--r--src/cmd/gc/subr.c148
-rw-r--r--src/cmd/gc/swt.c37
-rw-r--r--src/cmd/gc/typecheck.c420
-rw-r--r--src/cmd/gc/walk.c1189
-rw-r--r--src/cmd/gc/y.tab.c3983
-rw-r--r--src/cmd/gc/y.tab.h62
-rw-r--r--src/cmd/gc/yerr.h9
35 files changed, 6715 insertions, 3758 deletions
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c
index 6982bbe56..be9f552f6 100644
--- a/src/cmd/gc/align.c
+++ b/src/cmd/gc/align.c
@@ -15,8 +15,8 @@
static int defercalc;
-uint32
-rnd(uint32 o, uint32 r)
+vlong
+rnd(vlong o, vlong r)
{
if(r < 1 || r > 8 || (r&(r-1)) != 0)
fatal("rnd");
@@ -54,6 +54,11 @@ widstruct(Type *errtype, Type *t, vlong o, int flag)
for(f=t->type; f!=T; f=f->down) {
if(f->etype != TFIELD)
fatal("widstruct: not TFIELD: %lT", f);
+ if(f->type == T) {
+ // broken field, just skip it so that other valid fields
+ // get a width.
+ continue;
+ }
dowidth(f->type);
if(f->type->align > maxalign)
maxalign = f->type->align;
@@ -248,8 +253,12 @@ dowidth(Type *t)
checkwidth(t->type);
t->align = widthptr;
}
- else if(t->bound == -100)
- yyerror("use of [...] array outside of array literal");
+ else if(t->bound == -100) {
+ if(!t->broke) {
+ yyerror("use of [...] array outside of array literal");
+ t->broke = 1;
+ }
+ }
else
fatal("dowidth %T", t); // probably [...]T
break;
@@ -607,7 +616,7 @@ typeinit(void)
fatal("typeinit: %s already defined", s->name);
t = typ(etype);
- t->sym = s;
+ t->sym = s1;
dowidth(t);
types[etype] = t;
@@ -615,12 +624,12 @@ typeinit(void)
}
Array_array = rnd(0, widthptr);
- Array_nel = rnd(Array_array+widthptr, types[TUINT32]->width);
- Array_cap = rnd(Array_nel+types[TUINT32]->width, types[TUINT32]->width);
- sizeof_Array = rnd(Array_cap+types[TUINT32]->width, widthptr);
+ Array_nel = rnd(Array_array+widthptr, widthint);
+ Array_cap = rnd(Array_nel+widthint, widthint);
+ sizeof_Array = rnd(Array_cap+widthint, widthptr);
// string is same as slice wo the cap
- sizeof_String = rnd(Array_nel+types[TUINT32]->width, widthptr);
+ sizeof_String = rnd(Array_nel+widthint, widthptr);
dowidth(types[TSTRING]);
dowidth(idealstring);
diff --git a/src/cmd/gc/bisonerrors b/src/cmd/gc/bisonerrors
index 0f865d086..8886a8e52 100755
--- a/src/cmd/gc/bisonerrors
+++ b/src/cmd/gc/bisonerrors
@@ -41,9 +41,9 @@ grammar && NF>0 {
}
# In state dumps, record shift/reduce actions.
-bison && /^state 0/ { grammar = 0; states = 1 }
+bison && /^[Ss]tate 0/ { grammar = 0; states = 1 }
-states && /^state / { state = $2 }
+states && /^[Ss]tate / { state = $2 }
states { statetext[state] = statetext[state] $0 "\n" }
states && / shift/ {
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
index ca3d6670d..7de448d1e 100644
--- a/src/cmd/gc/builtin.c
+++ b/src/cmd/gc/builtin.c
@@ -1,118 +1,119 @@
char *runtimeimport =
"package runtime\n"
"import runtime \"runtime\"\n"
- "func @\"\".new(@\"\".typ *byte) (? *any)\n"
- "func @\"\".panicindex()\n"
- "func @\"\".panicslice()\n"
- "func @\"\".throwreturn()\n"
- "func @\"\".throwinit()\n"
- "func @\"\".panicwrap(? string, ? string, ? string)\n"
- "func @\"\".panic(? interface {})\n"
- "func @\"\".recover(? *int32) (? interface {})\n"
- "func @\"\".printbool(? bool)\n"
- "func @\"\".printfloat(? float64)\n"
- "func @\"\".printint(? int64)\n"
- "func @\"\".printuint(? uint64)\n"
- "func @\"\".printcomplex(? complex128)\n"
- "func @\"\".printstring(? string)\n"
- "func @\"\".printpointer(? any)\n"
- "func @\"\".printiface(? any)\n"
- "func @\"\".printeface(? any)\n"
- "func @\"\".printslice(? any)\n"
- "func @\"\".printnl()\n"
- "func @\"\".printsp()\n"
- "func @\"\".goprintf()\n"
- "func @\"\".concatstring()\n"
- "func @\"\".append()\n"
- "func @\"\".appendslice(@\"\".typ *byte, @\"\".x any, @\"\".y []any) (? any)\n"
- "func @\"\".appendstr(@\"\".typ *byte, @\"\".x []byte, @\"\".y string) (? []byte)\n"
- "func @\"\".cmpstring(? string, ? string) (? int)\n"
- "func @\"\".slicestring(? string, ? int, ? int) (? string)\n"
- "func @\"\".slicestring1(? string, ? int) (? string)\n"
- "func @\"\".intstring(? int64) (? string)\n"
- "func @\"\".slicebytetostring(? []byte) (? string)\n"
- "func @\"\".slicerunetostring(? []rune) (? string)\n"
- "func @\"\".stringtoslicebyte(? string) (? []byte)\n"
- "func @\"\".stringtoslicerune(? string) (? []rune)\n"
- "func @\"\".stringiter(? string, ? int) (? int)\n"
- "func @\"\".stringiter2(? string, ? int) (@\"\".retk int, @\"\".retv rune)\n"
- "func @\"\".copy(@\"\".to any, @\"\".fr any, @\"\".wid uint32) (? int)\n"
- "func @\"\".slicestringcopy(@\"\".to any, @\"\".fr any) (? int)\n"
- "func @\"\".convI2E(@\"\".elem any) (@\"\".ret any)\n"
- "func @\"\".convI2I(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n"
- "func @\"\".convT2E(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n"
- "func @\"\".convT2I(@\"\".typ *byte, @\"\".typ2 *byte, @\"\".elem any) (@\"\".ret any)\n"
- "func @\"\".assertE2E(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
- "func @\"\".assertE2E2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
- "func @\"\".assertE2I(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
- "func @\"\".assertE2I2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
- "func @\"\".assertE2T(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
- "func @\"\".assertE2T2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
- "func @\"\".assertI2E(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
- "func @\"\".assertI2E2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
- "func @\"\".assertI2I(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
- "func @\"\".assertI2I2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
- "func @\"\".assertI2T(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
- "func @\"\".assertI2T2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
- "func @\"\".ifaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n"
- "func @\"\".efaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n"
- "func @\"\".ifacethash(@\"\".i1 any) (@\"\".ret uint32)\n"
- "func @\"\".efacethash(@\"\".i1 any) (@\"\".ret uint32)\n"
- "func @\"\".equal(@\"\".typ *byte, @\"\".x1 any, @\"\".x2 any) (@\"\".ret bool)\n"
- "func @\"\".makemap(@\"\".mapType *byte, @\"\".hint int64) (@\"\".hmap map[any]any)\n"
- "func @\"\".mapaccess1(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any) (@\"\".val any)\n"
- "func @\"\".mapaccess2(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any) (@\"\".val any, @\"\".pres bool)\n"
- "func @\"\".mapassign1(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any, @\"\".val any)\n"
- "func @\"\".mapassign2(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any, @\"\".val any, @\"\".pres bool)\n"
- "func @\"\".mapiterinit(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".hiter *any)\n"
- "func @\"\".mapdelete(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any)\n"
- "func @\"\".mapiternext(@\"\".hiter *any)\n"
- "func @\"\".mapiter1(@\"\".hiter *any) (@\"\".key any)\n"
- "func @\"\".mapiter2(@\"\".hiter *any) (@\"\".key any, @\"\".val any)\n"
- "func @\"\".makechan(@\"\".chanType *byte, @\"\".hint int64) (@\"\".hchan chan any)\n"
- "func @\"\".chanrecv1(@\"\".chanType *byte, @\"\".hchan <-chan any) (@\"\".elem any)\n"
- "func @\"\".chanrecv2(@\"\".chanType *byte, @\"\".hchan <-chan any) (@\"\".elem any, @\"\".received bool)\n"
- "func @\"\".chansend1(@\"\".chanType *byte, @\"\".hchan chan<- any, @\"\".elem any)\n"
- "func @\"\".closechan(@\"\".hchan any)\n"
- "func @\"\".selectnbsend(@\"\".chanType *byte, @\"\".hchan chan<- any, @\"\".elem any) (? bool)\n"
- "func @\"\".selectnbrecv(@\"\".chanType *byte, @\"\".elem *any, @\"\".hchan <-chan any) (? bool)\n"
- "func @\"\".selectnbrecv2(@\"\".chanType *byte, @\"\".elem *any, @\"\".received *bool, @\"\".hchan <-chan any) (? bool)\n"
- "func @\"\".newselect(@\"\".size int) (@\"\".sel *byte)\n"
- "func @\"\".selectsend(@\"\".sel *byte, @\"\".hchan chan<- any, @\"\".elem *any) (@\"\".selected bool)\n"
- "func @\"\".selectrecv(@\"\".sel *byte, @\"\".hchan <-chan any, @\"\".elem *any) (@\"\".selected bool)\n"
- "func @\"\".selectrecv2(@\"\".sel *byte, @\"\".hchan <-chan any, @\"\".elem *any, @\"\".received *bool) (@\"\".selected bool)\n"
- "func @\"\".selectdefault(@\"\".sel *byte) (@\"\".selected bool)\n"
- "func @\"\".selectgo(@\"\".sel *byte)\n"
- "func @\"\".block()\n"
- "func @\"\".makeslice(@\"\".typ *byte, @\"\".nel int64, @\"\".cap int64) (@\"\".ary []any)\n"
- "func @\"\".growslice(@\"\".typ *byte, @\"\".old []any, @\"\".n int64) (@\"\".ary []any)\n"
- "func @\"\".sliceslice1(@\"\".old []any, @\"\".lb uint64, @\"\".width uint64) (@\"\".ary []any)\n"
- "func @\"\".sliceslice(@\"\".old []any, @\"\".lb uint64, @\"\".hb uint64, @\"\".width uint64) (@\"\".ary []any)\n"
- "func @\"\".slicearray(@\"\".old *any, @\"\".nel uint64, @\"\".lb uint64, @\"\".hb uint64, @\"\".width uint64) (@\"\".ary []any)\n"
- "func @\"\".closure()\n"
- "func @\"\".memequal(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n"
- "func @\"\".memequal8(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n"
- "func @\"\".memequal16(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n"
- "func @\"\".memequal32(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n"
- "func @\"\".memequal64(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n"
- "func @\"\".memequal128(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n"
- "func @\"\".int64div(? int64, ? int64) (? int64)\n"
- "func @\"\".uint64div(? uint64, ? uint64) (? uint64)\n"
- "func @\"\".int64mod(? int64, ? int64) (? int64)\n"
- "func @\"\".uint64mod(? uint64, ? uint64) (? uint64)\n"
- "func @\"\".float64toint64(? float64) (? int64)\n"
- "func @\"\".float64touint64(? float64) (? uint64)\n"
- "func @\"\".int64tofloat64(? int64) (? float64)\n"
- "func @\"\".uint64tofloat64(? uint64) (? float64)\n"
- "func @\"\".complex128div(@\"\".num complex128, @\"\".den complex128) (@\"\".quo complex128)\n"
+ "func @\"\".new (@\"\".typ·2 *byte) (? *any)\n"
+ "func @\"\".panicindex ()\n"
+ "func @\"\".panicslice ()\n"
+ "func @\"\".throwreturn ()\n"
+ "func @\"\".throwinit ()\n"
+ "func @\"\".panicwrap (? string, ? string, ? string)\n"
+ "func @\"\".panic (? interface {})\n"
+ "func @\"\".recover (? *int32) (? interface {})\n"
+ "func @\"\".printbool (? bool)\n"
+ "func @\"\".printfloat (? float64)\n"
+ "func @\"\".printint (? int64)\n"
+ "func @\"\".printuint (? uint64)\n"
+ "func @\"\".printcomplex (? complex128)\n"
+ "func @\"\".printstring (? string)\n"
+ "func @\"\".printpointer (? any)\n"
+ "func @\"\".printiface (? any)\n"
+ "func @\"\".printeface (? any)\n"
+ "func @\"\".printslice (? any)\n"
+ "func @\"\".printnl ()\n"
+ "func @\"\".printsp ()\n"
+ "func @\"\".goprintf ()\n"
+ "func @\"\".concatstring ()\n"
+ "func @\"\".append ()\n"
+ "func @\"\".appendslice (@\"\".typ·2 *byte, @\"\".x·3 any, @\"\".y·4 []any) (? any)\n"
+ "func @\"\".appendstr (@\"\".typ·2 *byte, @\"\".x·3 []byte, @\"\".y·4 string) (? []byte)\n"
+ "func @\"\".cmpstring (? string, ? string) (? int)\n"
+ "func @\"\".eqstring (? string, ? string) (? bool)\n"
+ "func @\"\".intstring (? int64) (? string)\n"
+ "func @\"\".slicebytetostring (? []byte) (? string)\n"
+ "func @\"\".slicerunetostring (? []rune) (? string)\n"
+ "func @\"\".stringtoslicebyte (? string) (? []byte)\n"
+ "func @\"\".stringtoslicerune (? string) (? []rune)\n"
+ "func @\"\".stringiter (? string, ? int) (? int)\n"
+ "func @\"\".stringiter2 (? string, ? int) (@\"\".retk·1 int, @\"\".retv·2 rune)\n"
+ "func @\"\".copy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr) (? int)\n"
+ "func @\"\".slicestringcopy (@\"\".to·2 any, @\"\".fr·3 any) (? int)\n"
+ "func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n"
+ "func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n"
+ "func @\"\".convI2I (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 any) (@\"\".ret·1 any)\n"
+ "func @\"\".assertE2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".assertE2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+ "func @\"\".assertE2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".assertE2I2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+ "func @\"\".assertE2T (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".assertE2T2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+ "func @\"\".assertI2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".assertI2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+ "func @\"\".assertI2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".assertI2I2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+ "func @\"\".assertI2T (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+ "func @\"\".assertI2T2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+ "func @\"\".assertI2TOK (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ok·1 bool)\n"
+ "func @\"\".assertE2TOK (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ok·1 bool)\n"
+ "func @\"\".ifaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n"
+ "func @\"\".efaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n"
+ "func @\"\".ifacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n"
+ "func @\"\".efacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n"
+ "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 @\"\".mapaccess2 (@\"\".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"
+ "func @\"\".mapiternext (@\"\".hiter·1 *any)\n"
+ "func @\"\".mapiter1 (@\"\".hiter·2 *any) (@\"\".key·1 any)\n"
+ "func @\"\".mapiter2 (@\"\".hiter·3 *any) (@\"\".key·1 any, @\"\".val·2 any)\n"
+ "func @\"\".makechan (@\"\".chanType·2 *byte, @\"\".hint·3 int64) (@\"\".hchan·1 chan any)\n"
+ "func @\"\".chanrecv1 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any) (@\"\".elem·1 any)\n"
+ "func @\"\".chanrecv2 (@\"\".chanType·3 *byte, @\"\".hchan·4 <-chan any) (@\"\".elem·1 any, @\"\".received·2 bool)\n"
+ "func @\"\".chansend1 (@\"\".chanType·1 *byte, @\"\".hchan·2 chan<- any, @\"\".elem·3 any)\n"
+ "func @\"\".closechan (@\"\".hchan·1 any)\n"
+ "func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 any) (? bool)\n"
+ "func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n"
+ "func @\"\".selectnbrecv2 (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".received·4 *bool, @\"\".hchan·5 <-chan any) (? bool)\n"
+ "func @\"\".newselect (@\"\".size·2 int32) (@\"\".sel·1 *byte)\n"
+ "func @\"\".selectsend (@\"\".sel·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n"
+ "func @\"\".selectrecv (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n"
+ "func @\"\".selectrecv2 (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any, @\"\".received·5 *bool) (@\"\".selected·1 bool)\n"
+ "func @\"\".selectdefault (@\"\".sel·2 *byte) (@\"\".selected·1 bool)\n"
+ "func @\"\".selectgo (@\"\".sel·1 *byte)\n"
+ "func @\"\".block ()\n"
+ "func @\"\".makeslice (@\"\".typ·2 *byte, @\"\".nel·3 int64, @\"\".cap·4 int64) (@\"\".ary·1 []any)\n"
+ "func @\"\".growslice (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".n·4 int64) (@\"\".ary·1 []any)\n"
+ "func @\"\".memequal (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
+ "func @\"\".memequal8 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
+ "func @\"\".memequal16 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
+ "func @\"\".memequal32 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
+ "func @\"\".memequal64 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
+ "func @\"\".memequal128 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
+ "func @\"\".int64div (? int64, ? int64) (? int64)\n"
+ "func @\"\".uint64div (? uint64, ? uint64) (? uint64)\n"
+ "func @\"\".int64mod (? int64, ? int64) (? int64)\n"
+ "func @\"\".uint64mod (? uint64, ? uint64) (? uint64)\n"
+ "func @\"\".float64toint64 (? float64) (? int64)\n"
+ "func @\"\".float64touint64 (? float64) (? uint64)\n"
+ "func @\"\".int64tofloat64 (? int64) (? float64)\n"
+ "func @\"\".uint64tofloat64 (? uint64) (? float64)\n"
+ "func @\"\".complex128div (@\"\".num·2 complex128, @\"\".den·3 complex128) (@\"\".quo·1 complex128)\n"
+ "func @\"\".racefuncenter (? uintptr)\n"
+ "func @\"\".racefuncexit ()\n"
+ "func @\"\".raceread (? uintptr)\n"
+ "func @\"\".racewrite (? uintptr)\n"
"\n"
"$$\n";
char *unsafeimport =
"package unsafe\n"
"import runtime \"runtime\"\n"
"type @\"\".Pointer uintptr\n"
- "func @\"\".Offsetof(? any) (? uintptr)\n"
- "func @\"\".Sizeof(? any) (? uintptr)\n"
- "func @\"\".Alignof(? any) (? uintptr)\n"
+ "func @\"\".Offsetof (? any) (? uintptr)\n"
+ "func @\"\".Sizeof (? any) (? uintptr)\n"
+ "func @\"\".Alignof (? any) (? uintptr)\n"
"\n"
"$$\n";
diff --git a/src/cmd/gc/closure.c b/src/cmd/gc/closure.c
index fa44e40fa..4e029ef83 100644
--- a/src/cmd/gc/closure.c
+++ b/src/cmd/gc/closure.c
@@ -75,6 +75,8 @@ closurebody(NodeList *body)
return func;
}
+static Node* makeclosure(Node *func, int nowrap);
+
void
typecheckclosure(Node *func, int top)
{
@@ -85,12 +87,12 @@ typecheckclosure(Node *func, int top)
oldfn = curfn;
typecheck(&func->ntype, Etype);
func->type = func->ntype->type;
- if(curfn == nil) {
- xtop = list(xtop, func);
- return;
- }
-
- if(func->type != T) {
+
+ // Type check the body now, but only if we're inside a function.
+ // At top level (in a variable initialization: curfn==nil) we're not
+ // ready to type check code yet; we'll check it later, because the
+ // underlying closure function we create is added to xtop.
+ if(curfn && func->type != T) {
curfn = func;
typechecklist(func->nbody, Etop);
curfn = oldfn;
@@ -120,26 +122,43 @@ typecheckclosure(Node *func, int top)
func->enter = list(func->enter, v->heapaddr);
v->heapaddr = N;
}
+
+ // Create top-level function
+ xtop = list(xtop, makeclosure(func, func->cvars==nil || (top&Ecall)));
}
static Node*
-makeclosure(Node *func, NodeList **init, int nowrap)
+makeclosure(Node *func, int nowrap)
{
- Node *xtype, *v, *addr, *xfunc;
- NodeList *l;
+ Node *xtype, *v, *addr, *xfunc, *cv;
+ NodeList *l, *body;
static int closgen;
char *p;
-
- USED(init);
+ int offset;
/*
* wrap body in external function
- * with extra closure parameters.
+ * that begins by reading closure parameters.
*/
xtype = nod(OTFUNC, N, N);
+ xtype->list = func->list;
+ xtype->rlist = func->rlist;
- // each closure variable has a corresponding
- // address parameter.
+ // create the function
+ xfunc = nod(ODCLFUNC, N, N);
+ snprint(namebuf, sizeof namebuf, "func·%.3d", ++closgen);
+ xfunc->nname = newname(lookup(namebuf));
+ xfunc->nname->sym->flags |= SymExported; // disable export
+ xfunc->nname->ntype = xtype;
+ xfunc->nname->defn = xfunc;
+ declare(xfunc->nname, PFUNC);
+ xfunc->nname->funcdepth = func->funcdepth;
+ xfunc->funcdepth = func->funcdepth;
+
+ // declare variables holding addresses taken from closure
+ // and initialize in entry prologue.
+ body = nil;
+ offset = widthptr;
for(l=func->cvars; l; l=l->next) {
v = l->n;
if(v->op == 0)
@@ -149,38 +168,35 @@ makeclosure(Node *func, NodeList **init, int nowrap)
addr->sym = lookup(p);
free(p);
addr->ntype = nod(OIND, typenod(v->type), N);
- addr->class = PPARAM;
+ addr->class = PAUTO;
addr->addable = 1;
addr->ullman = 1;
-
+ addr->used = 1;
+ addr->curfn = xfunc;
+ xfunc->dcl = list(xfunc->dcl, addr);
v->heapaddr = addr;
-
- xtype->list = list(xtype->list, nod(ODCLFIELD, addr, addr->ntype));
+ cv = nod(OCLOSUREVAR, N, N);
+ cv->type = ptrto(v->type);
+ cv->xoffset = offset;
+ body = list(body, nod(OAS, addr, cv));
+ offset += widthptr;
}
+ typechecklist(body, Etop);
+ walkstmtlist(body);
+ xfunc->enter = body;
- // then a dummy arg where the closure's caller pc sits
- if (!nowrap)
- xtype->list = list(xtype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
-
- // then the function arguments
- xtype->list = concat(xtype->list, func->list);
- xtype->rlist = concat(xtype->rlist, func->rlist);
-
- // create the function
- xfunc = nod(ODCLFUNC, N, N);
- snprint(namebuf, sizeof namebuf, "_func_%.3d", ++closgen);
- xfunc->nname = newname(lookup(namebuf));
- xfunc->nname->ntype = xtype;
- xfunc->nname->defn = xfunc;
- declare(xfunc->nname, PFUNC);
- xfunc->nname->funcdepth = func->funcdepth;
- xfunc->funcdepth = func->funcdepth;
xfunc->nbody = func->nbody;
- xfunc->dcl = func->dcl;
+ xfunc->dcl = concat(func->dcl, xfunc->dcl);
if(xfunc->nbody == nil)
fatal("empty body - won't generate any code");
typecheck(&xfunc, Etop);
- closures = list(closures, xfunc);
+
+ xfunc->closure = func;
+ func->closure = xfunc;
+
+ func->nbody = nil;
+ func->list = nil;
+ func->rlist = nil;
return xfunc;
}
@@ -188,51 +204,55 @@ makeclosure(Node *func, NodeList **init, int nowrap)
Node*
walkclosure(Node *func, NodeList **init)
{
+ Node *clos, *typ;
+ NodeList *l;
+ char buf[20];
int narg;
- Node *xtype, *xfunc, *call, *clos;
- NodeList *l, *in;
- // no closure vars, don't bother wrapping
+ // If no closure vars, don't bother wrapping.
if(func->cvars == nil)
- return makeclosure(func, init, 1)->nname;
+ return func->closure->nname;
+
+ // Create closure in the form of a composite literal.
+ // supposing the closure captures an int i and a string s
+ // and has one float64 argument and no results,
+ // the generated code looks like:
+ //
+ // clos = &struct{F uintptr; A0 *int; A1 *string}{func·001, &i, &s}
+ //
+ // The use of the struct provides type information to the garbage
+ // collector so that it can walk the closure. We could use (in this case)
+ // [3]unsafe.Pointer instead, but that would leave the gc in the dark.
+ // The information appears in the binary in the form of type descriptors;
+ // the struct is unnamed so that closures in multiple packages with the
+ // same struct type can share the descriptor.
- /*
- * wrap body in external function
- * with extra closure parameters.
- */
-
- // create the function
- xfunc = makeclosure(func, init, 0);
- xtype = xfunc->nname->ntype;
-
- // prepare call of sys.closure that turns external func into func literal value.
- clos = syslook("closure", 1);
- clos->type = T;
- clos->ntype = nod(OTFUNC, N, N);
- in = list1(nod(ODCLFIELD, N, typenod(types[TINT]))); // siz
- in = list(in, nod(ODCLFIELD, N, xtype));
narg = 0;
+ typ = nod(OTSTRUCT, N, N);
+ typ->list = list1(nod(ODCLFIELD, newname(lookup("F")), typenod(types[TUINTPTR])));
for(l=func->cvars; l; l=l->next) {
if(l->n->op == 0)
continue;
- narg++;
- in = list(in, nod(ODCLFIELD, N, l->n->heapaddr->ntype));
+ snprint(buf, sizeof buf, "A%d", narg++);
+ typ->list = list(typ->list, nod(ODCLFIELD, newname(lookup(buf)), l->n->heapaddr->ntype));
}
- clos->ntype->list = in;
- clos->ntype->rlist = list1(nod(ODCLFIELD, N, typenod(func->type)));
+
+ clos = nod(OCOMPLIT, N, nod(OIND, typ, N));
+ clos->esc = func->esc;
+ clos->right->implicit = 1;
+ clos->list = concat(list1(nod(OCFUNC, func->closure->nname, N)), func->enter);
+
+ // Force type conversion from *struct to the func type.
+ clos = nod(OCONVNOP, clos, N);
+ clos->type = func->type;
+
typecheck(&clos, Erv);
+ // typecheck will insert a PTRLIT node under CONVNOP,
+ // tag it with escape analysis result.
+ clos->left->esc = func->esc;
+ walkexpr(&clos, init);
- call = nod(OCALL, clos, N);
- if(narg*widthptr > 100)
- yyerror("closure needs too many variables; runtime will reject it");
- in = list1(nodintconst(narg*widthptr));
- in = list(in, xfunc->nname);
- in = concat(in, func->enter);
- call->list = in;
-
- typecheck(&call, Erv);
- walkexpr(&call, init);
- return call;
+ return clos;
}
// Special case for closures that get called in place.
@@ -242,6 +262,7 @@ walkclosure(Node *func, NodeList **init)
void
walkcallclosure(Node *n, NodeList **init)
{
+ USED(init);
if (n->op != OCALLFUNC || n->left->op != OCLOSURE) {
dump("walkcallclosure", n);
fatal("abuse of walkcallclosure");
@@ -250,7 +271,7 @@ walkcallclosure(Node *n, NodeList **init)
// 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 = makeclosure(n->left, init, 1)->nname;
+ 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
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index e27c88338..4f1ff6778 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -87,8 +87,12 @@ convlit1(Node **np, Type *t, int explicit)
switch(n->op) {
default:
- if(n->type == idealbool)
- n->type = types[TBOOL];
+ if(n->type == idealbool) {
+ if(t->etype == TBOOL)
+ n->type = t;
+ else
+ n->type = types[TBOOL];
+ }
if(n->type->etype == TIDEAL) {
convlit(&n->left, t);
convlit(&n->right, t);
@@ -162,6 +166,16 @@ convlit1(Node **np, Type *t, int explicit)
case TFUNC:
case TUNSAFEPTR:
break;
+
+ case TUINTPTR:
+ // A nil literal may be converted to uintptr
+ // if it is an unsafe.Pointer
+ if(n->type->etype == TUNSAFEPTR) {
+ n->val.u.xval = mal(sizeof(*n->val.u.xval));
+ mpmovecfix(n->val.u.xval, 0);
+ n->val.ctype = CTINT;
+ } else
+ goto bad;
}
break;
@@ -230,7 +244,8 @@ convlit1(Node **np, Type *t, int explicit)
bad:
if(!n->diag) {
- yyerror("cannot convert %N to type %T", n, t);
+ if(!t->broke)
+ yyerror("cannot convert %N to type %T", n, t);
n->diag = 1;
}
if(isideal(n->type)) {
@@ -348,13 +363,9 @@ toint(Val v)
return v;
}
-void
-overflow(Val v, Type *t)
+int
+doesoverflow(Val v, Type *t)
{
- // v has already been converted
- // to appropriate form for t.
- if(t == T || t->etype == TIDEAL)
- return;
switch(v.ctype) {
case CTINT:
case CTRUNE:
@@ -362,14 +373,14 @@ overflow(Val v, Type *t)
fatal("overflow: %T integer constant", t);
if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0 ||
mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0)
- yyerror("constant %B overflows %T", v.u.xval, t);
+ return 1;
break;
case CTFLT:
if(!isfloat[t->etype])
fatal("overflow: %T floating-point constant", t);
if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) <= 0 ||
mpcmpfltflt(v.u.fval, maxfltval[t->etype]) >= 0)
- yyerror("constant %#F overflows %T", v.u.fval, t);
+ return 1;
break;
case CTCPLX:
if(!iscomplex[t->etype])
@@ -378,7 +389,33 @@ overflow(Val v, Type *t)
mpcmpfltflt(&v.u.cval->real, maxfltval[t->etype]) >= 0 ||
mpcmpfltflt(&v.u.cval->imag, minfltval[t->etype]) <= 0 ||
mpcmpfltflt(&v.u.cval->imag, maxfltval[t->etype]) >= 0)
- yyerror("constant %#F overflows %T", v.u.fval, t);
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+void
+overflow(Val v, Type *t)
+{
+ // v has already been converted
+ // to appropriate form for t.
+ if(t == T || t->etype == TIDEAL)
+ return;
+
+ if(!doesoverflow(v, t))
+ return;
+
+ switch(v.ctype) {
+ case CTINT:
+ case CTRUNE:
+ yyerror("constant %B overflows %T", v.u.xval, t);
+ break;
+ case CTFLT:
+ yyerror("constant %#F overflows %T", v.u.fval, t);
+ break;
+ case CTCPLX:
+ yyerror("constant %#F overflows %T", v.u.fval, t);
break;
}
}
@@ -437,6 +474,20 @@ isconst(Node *n, int ct)
return t == ct || (ct == CTINT && t == CTRUNE);
}
+static Node*
+saveorig(Node *n)
+{
+ Node *n1;
+
+ if(n == n->orig) {
+ // duplicate node for n->orig.
+ n1 = nod(OLITERAL, N, N);
+ n->orig = n1;
+ *n1 = *n;
+ }
+ return n->orig;
+}
+
/*
* if n is constant, rewrite as OLITERAL node.
*/
@@ -902,12 +953,7 @@ unary:
}
ret:
- if(n == n->orig) {
- // duplicate node for n->orig.
- norig = nod(OLITERAL, N, N);
- *norig = *n;
- } else
- norig = n->orig;
+ norig = saveorig(n);
*n = *nl;
// restore value of n->orig.
n->orig = norig;
@@ -924,11 +970,15 @@ ret:
return;
settrue:
+ norig = saveorig(n);
*n = *nodbool(1);
+ n->orig = norig;
return;
setfalse:
+ norig = saveorig(n);
*n = *nodbool(0);
+ n->orig = norig;
return;
}
@@ -984,79 +1034,88 @@ nodcplxlit(Val r, Val i)
return n;
}
-// TODO(rsc): combine with convlit
+// idealkind returns a constant kind like consttype
+// but for an arbitrary "ideal" expression.
+static int
+idealkind(Node *n)
+{
+ int k1, k2;
+
+ if(n == N || !isideal(n->type))
+ return CTxxx;
+
+ switch(n->op) {
+ default:
+ return CTxxx;
+ case OLITERAL:
+ return n->val.ctype;
+ case OADD:
+ case OAND:
+ case OANDNOT:
+ case OCOM:
+ case ODIV:
+ case OMINUS:
+ case OMOD:
+ case OMUL:
+ case OSUB:
+ case OXOR:
+ case OOR:
+ case OPLUS:
+ // numeric kinds.
+ k1 = idealkind(n->left);
+ k2 = idealkind(n->right);
+ if(k1 > k2)
+ return k1;
+ else
+ return k2;
+ case OADDSTR:
+ return CTSTR;
+ case OANDAND:
+ case OEQ:
+ case OGE:
+ case OGT:
+ case OLE:
+ case OLT:
+ case ONE:
+ case ONOT:
+ case OOROR:
+ case OCMPSTR:
+ case OCMPIFACE:
+ return CTBOOL;
+ case OLSH:
+ case ORSH:
+ // shifts (beware!).
+ return idealkind(n->left);
+ }
+}
+
void
defaultlit(Node **np, Type *t)
{
int lno;
+ int ctype;
Node *n, *nn;
+ Type *t1;
n = *np;
if(n == N || !isideal(n->type))
return;
- switch(n->op) {
- case OLITERAL:
+ if(n->op == OLITERAL) {
nn = nod(OXXX, N, N);
*nn = *n;
n = nn;
*np = n;
- break;
- case OLSH:
- case ORSH:
- defaultlit(&n->left, t);
- t = n->left->type;
- if(t != T && !isint[t->etype]) {
- yyerror("invalid operation: %N (shift of type %T)", n, t);
- t = T;
- }
- n->type = t;
- return;
- case ONOT:
- defaultlit(&n->left, t);
- n->type = n->left->type;
- return;
- default:
- if(n->left == N) {
- dump("defaultlit", n);
- fatal("defaultlit");
- }
- // n is ideal, so left and right must both be ideal.
- // n has not been computed as a constant value,
- // so either left or right must not be constant.
- // The only 'ideal' non-constant expressions are shifts. Ugh.
- // If one of these is a shift and the other is not, use that type.
- // When compiling x := 1<<i + 3.14, this means we try to push
- // the float64 down into the 1<<i, producing the correct error
- // (cannot shift float64).
- if(t == T && (n->right->op == OLSH || n->right->op == ORSH)) {
- defaultlit(&n->left, T);
- defaultlit(&n->right, n->left->type);
- } else if(t == T && (n->left->op == OLSH || n->left->op == ORSH)) {
- defaultlit(&n->right, T);
- defaultlit(&n->left, n->right->type);
- } else if(iscmp[n->op]) {
- defaultlit2(&n->left, &n->right, 1);
- } else {
- defaultlit(&n->left, t);
- defaultlit(&n->right, t);
- }
- if(n->type == idealbool || n->type == idealstring) {
- if(t != T && t->etype == n->type->etype)
- n->type = t;
- else
- n->type = types[n->type->etype];
- } else
- n->type = n->left->type;
- return;
}
lno = setlineno(n);
- switch(n->val.ctype) {
+ ctype = idealkind(n);
+ t1 = T;
+ switch(ctype) {
default:
if(t != T) {
convlit(np, t);
- break;
+ return;
}
if(n->val.ctype == CTNIL) {
lineno = lno;
@@ -1065,46 +1124,52 @@ defaultlit(Node **np, Type *t)
break;
}
if(n->val.ctype == CTSTR) {
- n->type = types[TSTRING];
+ t1 = types[TSTRING];
+ convlit(np, t1);
break;
}
yyerror("defaultlit: unknown literal: %N", n);
break;
+ case CTxxx:
+ fatal("defaultlit: idealkind is CTxxx: %+N", n);
+ break;
case CTBOOL:
- n->type = types[TBOOL];
+ t1 = types[TBOOL];
if(t != T && t->etype == TBOOL)
- n->type = t;
+ t1 = t;
+ convlit(np, t1);
break;
case CTINT:
- n->type = types[TINT];
+ t1 = types[TINT];
goto num;
case CTRUNE:
- n->type = runetype;
+ t1 = runetype;
goto num;
case CTFLT:
- n->type = types[TFLOAT64];
+ t1 = types[TFLOAT64];
goto num;
case CTCPLX:
- n->type = types[TCOMPLEX128];
+ t1 = types[TCOMPLEX128];
goto num;
num:
if(t != T) {
if(isint[t->etype]) {
- n->type = t;
+ t1 = t;
n->val = toint(n->val);
}
else
if(isfloat[t->etype]) {
- n->type = t;
+ t1 = t;
n->val = toflt(n->val);
}
else
if(iscomplex[t->etype]) {
- n->type = t;
+ t1 = t;
n->val = tocplx(n->val);
}
}
- overflow(n->val, n->type);
+ overflow(n->val, t1);
+ convlit(np, t1);
break;
}
lineno = lno;
@@ -1206,6 +1271,7 @@ smallintconst(Node *n)
case TIDEAL:
case TINT64:
case TUINT64:
+ case TPTR64:
if(mpcmpfixfix(n->val.u.xval, minintval[TINT32]) < 0
|| mpcmpfixfix(n->val.u.xval, maxintval[TINT32]) > 0)
break;
@@ -1392,3 +1458,132 @@ cmplxdiv(Mpcplx *v, Mpcplx *rv)
mpsubfltflt(&v->imag, &ad); // bc-ad
mpdivfltflt(&v->imag, &cc_plus_dd); // (bc+ad)/(cc+dd)
}
+
+static int hascallchan(Node*);
+
+// Is n a Go language constant (as opposed to a compile-time constant)?
+// Expressions derived from nil, like string([]byte(nil)), while they
+// may be known at compile time, are not Go language constants.
+// Only called for expressions known to evaluated to compile-time
+// constants.
+int
+isgoconst(Node *n)
+{
+ Node *l;
+ Type *t;
+
+ if(n->orig != N)
+ n = n->orig;
+
+ switch(n->op) {
+ case OADD:
+ case OADDSTR:
+ case OAND:
+ case OANDAND:
+ case OANDNOT:
+ case OCOM:
+ case ODIV:
+ case OEQ:
+ case OGE:
+ case OGT:
+ case OLE:
+ case OLSH:
+ case OLT:
+ case OMINUS:
+ case OMOD:
+ case OMUL:
+ case ONE:
+ case ONOT:
+ case OOR:
+ case OOROR:
+ case OPLUS:
+ case ORSH:
+ case OSUB:
+ case OXOR:
+ case OCONV:
+ case OIOTA:
+ case OCOMPLEX:
+ case OREAL:
+ case OIMAG:
+ if(isgoconst(n->left) && (n->right == N || isgoconst(n->right)))
+ return 1;
+ break;
+
+ case OLEN:
+ case OCAP:
+ l = n->left;
+ if(isgoconst(l))
+ return 1;
+ // Special case: len/cap is constant when applied to array or
+ // pointer to array when the expression does not contain
+ // function calls or channel receive operations.
+ t = l->type;
+ if(t != T && isptr[t->etype])
+ t = t->type;
+ if(isfixedarray(t) && !hascallchan(l))
+ return 1;
+ break;
+
+ case OLITERAL:
+ if(n->val.ctype != CTNIL)
+ return 1;
+ break;
+
+ case ONAME:
+ l = n->sym->def;
+ if(l->op == OLITERAL && n->val.ctype != CTNIL)
+ return 1;
+ break;
+
+ case ONONAME:
+ if(n->sym->def != N && n->sym->def->op == OIOTA)
+ return 1;
+ break;
+
+ case OCALL:
+ // Only constant calls are unsafe.Alignof, Offsetof, and Sizeof.
+ l = n->left;
+ while(l->op == OPAREN)
+ l = l->left;
+ if(l->op != ONAME || l->sym->pkg != unsafepkg)
+ break;
+ if(strcmp(l->sym->name, "Alignof") == 0 ||
+ strcmp(l->sym->name, "Offsetof") == 0 ||
+ strcmp(l->sym->name, "Sizeof") == 0)
+ return 1;
+ break;
+ }
+
+ //dump("nonconst", n);
+ return 0;
+}
+
+static int
+hascallchan(Node *n)
+{
+ NodeList *l;
+
+ if(n == N)
+ return 0;
+ switch(n->op) {
+ case OCALL:
+ case OCALLFUNC:
+ case OCALLMETH:
+ case OCALLINTER:
+ case ORECV:
+ return 1;
+ }
+
+ if(hascallchan(n->left) ||
+ hascallchan(n->right))
+ return 1;
+
+ for(l=n->list; l; l=l->next)
+ if(hascallchan(l->n))
+ return 1;
+ for(l=n->rlist; l; l=l->next)
+ if(hascallchan(l->n))
+ return 1;
+
+ return 0;
+}
diff --git a/src/cmd/gc/cplx.c b/src/cmd/gc/cplx.c
index dea7bc3bb..e0127fc59 100644
--- a/src/cmd/gc/cplx.c
+++ b/src/cmd/gc/cplx.c
@@ -271,7 +271,7 @@ complexgen(Node *n, Node *res)
}
void
-complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
+complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to)
{
Node tnl, tnr;
Node n1, n2, n3, n4;
@@ -323,7 +323,7 @@ complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
if(op == ONE)
true = !true;
- bgen(&na, true, to);
+ bgen(&na, true, likely, to);
}
void
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index 32f334b71..aa2489d9a 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -150,16 +150,35 @@ testdclstack(void)
void
redeclare(Sym *s, char *where)
{
- if(s->lastlineno == 0)
- yyerror("%S redeclared %s\n"
- "\tprevious declaration during import",
- s, where);
- else
+ Strlit *pkgstr;
+ int line1, line2;
+
+ if(s->lastlineno == 0) {
+ pkgstr = s->origpkg ? s->origpkg->path : s->pkg->path;
yyerror("%S redeclared %s\n"
+ "\tprevious declaration during import \"%Z\"",
+ s, where, pkgstr);
+ } else {
+ line1 = parserline();
+ line2 = s->lastlineno;
+
+ // When an import and a declaration collide in separate files,
+ // present the import as the "redeclared", because the declaration
+ // is visible where the import is, but not vice versa.
+ // See issue 4510.
+ if(s->def == N) {
+ line2 = line1;
+ line1 = s->lastlineno;
+ }
+
+ yyerrorl(line1, "%S redeclared %s\n"
"\tprevious declaration at %L",
- s, where, s->lastlineno);
+ s, where, line2);
+ }
}
+static int vargen;
+
/*
* declare individual names - var, typ, const
*/
@@ -168,7 +187,10 @@ declare(Node *n, int ctxt)
{
Sym *s;
int gen;
- static int typegen, vargen;
+ static int typegen;
+
+ if(ctxt == PDISCARD)
+ return;
if(isblank(n))
return;
@@ -180,6 +202,9 @@ declare(Node *n, int ctxt)
if(importpkg == nil && !typecheckok && s->pkg != localpkg)
yyerror("cannot declare name %S", s);
+ if(ctxt == PEXTERN && strcmp(s->name, "init") == 0)
+ yyerror("cannot declare init - must be func", s);
+
gen = 0;
if(ctxt == PEXTERN) {
externdcl = list(externdcl, n);
@@ -192,7 +217,7 @@ declare(Node *n, int ctxt)
curfn->dcl = list(curfn->dcl, n);
if(n->op == OTYPE)
gen = ++typegen;
- else if(n->op == ONAME)
+ else if(n->op == ONAME && ctxt == PAUTO && strstr(s->name, "·") == nil)
gen = ++vargen;
pushdcl(s);
n->curfn = curfn;
@@ -237,7 +262,7 @@ variter(NodeList *vl, Node *t, NodeList *el)
init = nil;
doexpr = el != nil;
-
+
if(count(el) == 1 && count(vl) > 1) {
e = el->n;
as2 = nod(OAS2, N, N);
@@ -464,7 +489,7 @@ colasdefn(NodeList *left, Node *defn)
if(isblank(n))
continue;
if(!colasname(n)) {
- yyerror("non-name %N on left side of :=", n);
+ yyerrorl(defn->lineno, "non-name %N on left side of :=", n);
nerr++;
continue;
}
@@ -479,11 +504,11 @@ colasdefn(NodeList *left, Node *defn)
l->n = n;
}
if(nnew == 0 && nerr == 0)
- yyerror("no new variables on left side of :=");
+ yyerrorl(defn->lineno, "no new variables on left side of :=");
}
Node*
-colas(NodeList *left, NodeList *right)
+colas(NodeList *left, NodeList *right, int32 lno)
{
Node *as;
@@ -491,6 +516,7 @@ colas(NodeList *left, NodeList *right)
as->list = left;
as->rlist = right;
as->colas = 1;
+ as->lineno = lno;
colasdefn(left, as);
// make the tree prettier; not necessary
@@ -515,7 +541,7 @@ ifacedcl(Node *n)
if(n->op != ODCLFIELD || n->right == N)
fatal("ifacedcl");
- dclcontext = PAUTO;
+ dclcontext = PPARAM;
markdcl();
funcdepth++;
n->outer = curfn;
@@ -526,6 +552,7 @@ ifacedcl(Node *n)
// seen the body of a function but since an interface
// field declaration does not have a body, we must
// call it now to pop the current declaration context.
+ dclcontext = PAUTO;
funcbody(n);
}
@@ -567,6 +594,11 @@ funcargs(Node *nt)
if(nt->op != OTFUNC)
fatal("funcargs %O", nt->op);
+ // re-start the variable generation number
+ // we want to use small numbers for the return variables,
+ // so let them have the chunk starting at 1.
+ vargen = count(nt->rlist);
+
// declare the receiver and in arguments.
// no n->defn because type checking of func header
// will not fill in the types until later
@@ -578,6 +610,8 @@ funcargs(Node *nt)
n->left->op = ONAME;
n->left->ntype = n->right;
declare(n->left, PPARAM);
+ if(dclcontext == PAUTO)
+ n->left->vargen = ++vargen;
}
}
for(l=nt->list; l; l=l->next) {
@@ -588,29 +622,44 @@ funcargs(Node *nt)
n->left->op = ONAME;
n->left->ntype = n->right;
declare(n->left, PPARAM);
+ if(dclcontext == PAUTO)
+ n->left->vargen = ++vargen;
}
}
// declare the out arguments.
- gen = 0;
+ gen = count(nt->list);
+ int i = 0;
for(l=nt->rlist; l; l=l->next) {
n = l->n;
+
if(n->op != ODCLFIELD)
fatal("funcargs out %O", n->op);
- if(n->left != N) {
- n->left->op = ONAME;
- n->left->ntype = n->right;
- if(isblank(n->left)) {
- // 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);
- }
- declare(n->left, PPARAMOUT);
+
+ if(n->left == N) {
+ // give it a name so escape analysis has nodes to work with
+ snprint(namebuf, sizeof(namebuf), "~anon%d", gen++);
+ n->left = newname(lookup(namebuf));
+ // TODO: n->left->missing = 1;
+ }
+
+ n->left->op = ONAME;
+
+ if(isblank(n->left)) {
+ // 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);
+ if(dclcontext == PAUTO)
+ n->left->vargen = ++i;
}
}
@@ -978,8 +1027,11 @@ embedded(Sym *s)
*utfrune(name, CenterDot) = 0;
}
- if(exportname(name) || s->pkg == builtinpkg) // old behaviour, tests pass, but is it correct?
+ if(exportname(name))
n = newname(lookup(name));
+ else if(s->pkg == builtinpkg && importpkg != nil)
+ // The name of embedded builtins during imports belongs to importpkg.
+ n = newname(pkglookup(name, importpkg));
else
n = newname(pkglookup(name, s->pkg));
n = nod(ODCLFIELD, n, oldname(s));
@@ -1124,6 +1176,7 @@ functype(Node *this, NodeList *in, NodeList *out)
{
Type *t;
NodeList *rcvr;
+ Sym *s;
t = typ(TFUNC);
@@ -1141,7 +1194,12 @@ functype(Node *this, NodeList *in, NodeList *out)
t->thistuple = 1;
t->outtuple = count(out);
t->intuple = count(in);
- t->outnamed = t->outtuple > 0 && out->n->left != N;
+ t->outnamed = 0;
+ if(t->outtuple > 0 && out->n->left != N && out->n->left->orig != N) {
+ s = out->n->left->orig->sym;
+ if(s != S && s->name[0] != '~')
+ t->outnamed = 1;
+ }
return t;
}
@@ -1249,7 +1307,7 @@ methodname1(Node *n, Node *t)
* n is fieldname, pa is base type, t is function type
*/
void
-addmethod(Sym *sf, Type *t, int local)
+addmethod(Sym *sf, Type *t, int local, int nointerface)
{
Type *f, *d, *pa;
Node *n;
@@ -1332,6 +1390,7 @@ addmethod(Sym *sf, Type *t, int local)
}
f = structfield(n);
+ f->nointerface = nointerface;
// during import unexported method names should be in the type's package
if(importpkg && f->sym && !exportname(f->sym->name) && f->sym->pkg != structpkg)
@@ -1382,3 +1441,20 @@ funccompile(Node *n, int isclosure)
funcdepth = 0;
dclcontext = PEXTERN;
}
+
+Sym*
+funcsym(Sym *s)
+{
+ char *p;
+ Sym *s1;
+
+ p = smprint("%s·f", s->name);
+ s1 = pkglookup(p, s->pkg);
+ free(p);
+ if(s1->def == N) {
+ s1->def = newname(s1);
+ s1->def->shortname = newname(s);
+ funcsyms = list(funcsyms, s1->def);
+ }
+ return s1;
+}
diff --git a/src/cmd/gc/doc.go b/src/cmd/gc/doc.go
index 8d8f8967b..791967708 100644
--- a/src/cmd/gc/doc.go
+++ b/src/cmd/gc/doc.go
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// +build ignore
+
/*
Gc is the generic label for the family of Go compilers
@@ -25,6 +27,8 @@ other packages. It is therefore not necessary when compiling client C of
package P to read the files of P's dependencies, only the compiled output
of P.
+Command Line
+
Usage:
go tool 6g [flags] file...
The specified files must be Go source files and all part of the same package.
@@ -48,15 +52,40 @@ Flags:
disable optimizations
-S
write assembly language text to standard output (code only)
- -SS
+ -S -S
write assembly language text to standard output (code and data)
-u
disallow importing packages not marked as safe
-V
print the compiler version
+ -race
+ compile with race detection enabled
There are also a number of debugging flags; run the command with no arguments
to get a usage message.
+Compiler Directives
+
+The compiler accepts two compiler directives in the form of // comments at the
+beginning of a line. To distinguish them from non-directive comments, the directives
+require no space between the slashes and the name of the directive. However, since
+they are comments, tools unaware of the directive convention or of a particular
+directive can skip over a directive like any other comment.
+
+ //line path/to/file:linenumber
+
+The //line directive specifies that the source line that follows should be recorded
+as having come from the given file path and line number. Successive lines are
+recorded using increasing line numbers, until the next directive. This directive
+typically appears in machine-generated code, so that compilers and debuggers
+will show lines in the original input to the generator.
+
+ //go:noescape
+
+The //go:noescape directive specifies that the next declaration in the file, which
+must be a func without a body (meaning that it has an implementation not written
+in Go) does not allow any of the pointers passed as arguments to escape into the
+heap or into the values returned from the function. This information can be used as
+during the compiler's escape analysis of Go code calling the function.
*/
-package documentation
+package main
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
index 8a265ce59..46c06d10e 100644
--- a/src/cmd/gc/esc.c
+++ b/src/cmd/gc/esc.c
@@ -1,8 +1,162 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//
+
// Escape analysis.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+// Run analysis on minimal sets of mutually recursive functions
+// or single non-recursive functions, bottom up.
+//
+// Finding these sets is finding strongly connected components
+// in the static call graph. The algorithm for doing that is taken
+// from Sedgewick, Algorithms, Second Edition, p. 482, with two
+// adaptations.
+//
+// First, a hidden closure function (n->curfn != N) cannot be the
+// root of a connected component. Refusing to use it as a root
+// forces it into the component of the function in which it appears.
+// The analysis assumes that closures and the functions in which they
+// appear are analyzed together, so that the aliasing between their
+// variables can be modeled more precisely.
+//
+// Second, each function becomes two virtual nodes in the graph,
+// with numbers n and n+1. We record the function's node number as n
+// but search from node n+1. If the search tells us that the component
+// number (min) is n+1, we know that this is a trivial component: one function
+// plus its closures. If the search tells us that the component number is
+// n, then there was a path from node n+1 back to node n, meaning that
+// the function set is mutually recursive. The escape analysis can be
+// more precise when analyzing a single non-recursive function than
+// when analyzing a set of mutually recursive functions.
+
+static NodeList *stack;
+static uint32 visitgen;
+static uint32 visit(Node*);
+static uint32 visitcode(Node*, uint32);
+static uint32 visitcodelist(NodeList*, uint32);
+
+static void analyze(NodeList*, int);
+
+enum
+{
+ EscFuncUnknown = 0,
+ EscFuncPlanned,
+ EscFuncStarted,
+ EscFuncTagged,
+};
+
+void
+escapes(NodeList *all)
+{
+ NodeList *l;
+
+ for(l=all; l; l=l->next)
+ l->n->walkgen = 0;
+
+ visitgen = 0;
+ for(l=all; l; l=l->next)
+ if(l->n->op == ODCLFUNC && l->n->curfn == N)
+ visit(l->n);
+
+ for(l=all; l; l=l->next)
+ l->n->walkgen = 0;
+}
+
+static uint32
+visit(Node *n)
+{
+ uint32 min, recursive;
+ NodeList *l, *block;
+
+ if(n->walkgen > 0) {
+ // already visited
+ return n->walkgen;
+ }
+
+ visitgen++;
+ n->walkgen = visitgen;
+ visitgen++;
+ min = visitgen;
+
+ l = mal(sizeof *l);
+ l->next = stack;
+ l->n = n;
+ stack = l;
+ min = visitcodelist(n->nbody, min);
+ if((min == n->walkgen || min == n->walkgen+1) && n->curfn == N) {
+ // This node is the root of a strongly connected component.
+
+ // The original min passed to visitcodelist was n->walkgen+1.
+ // If visitcodelist found its way back to n->walkgen, then this
+ // block is a set of mutually recursive functions.
+ // Otherwise it's just a lone function that does not recurse.
+ recursive = min == n->walkgen;
+
+ // Remove connected component from stack.
+ // Mark walkgen so that future visits return a large number
+ // so as not to affect the caller's min.
+ block = stack;
+ for(l=stack; l->n != n; l=l->next)
+ l->n->walkgen = (uint32)~0U;
+ n->walkgen = (uint32)~0U;
+ stack = l->next;
+ l->next = nil;
+
+ // Run escape analysis on this set of functions.
+ analyze(block, recursive);
+ }
+
+ return min;
+}
+
+static uint32
+visitcodelist(NodeList *l, uint32 min)
+{
+ for(; l; l=l->next)
+ min = visitcode(l->n, min);
+ return min;
+}
+
+static uint32
+visitcode(Node *n, uint32 min)
+{
+ Node *fn;
+ uint32 m;
+
+ if(n == N)
+ return min;
+
+ min = visitcodelist(n->ninit, min);
+ min = visitcode(n->left, min);
+ min = visitcode(n->right, min);
+ min = visitcodelist(n->list, min);
+ min = visitcode(n->ntest, min);
+ min = visitcode(n->nincr, min);
+ min = visitcodelist(n->nbody, min);
+ min = visitcodelist(n->nelse, min);
+ min = visitcodelist(n->rlist, min);
+
+ if(n->op == OCALLFUNC || n->op == OCALLMETH) {
+ fn = n->left;
+ if(n->op == OCALLMETH)
+ fn = n->left->right->sym->def;
+ if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody)
+ if((m = visit(fn->defn)) < min)
+ min = m;
+ }
+
+ if(n->op == OCLOSURE)
+ if((m = visit(n->closure)) < min)
+ min = m;
+
+ return min;
+}
+
+// An escape analysis pass for a set of functions.
//
// First escfunc, esc and escassign recurse over the ast of each
// function to dig out flow(dst,src) edges between any
@@ -22,75 +176,123 @@
// not escape, then new(T) can be rewritten into a stack allocation.
// The same is true of slice literals.
//
-// If escape analysis is disabled (-s), this code is not used.
+// If optimizations are disabled (-N), this code is not used.
// Instead, the compiler assumes that any value whose address
// is taken without being immediately dereferenced
// needs to be moved to the heap, and new(T) and slice
// literals are always real allocations.
-#include <u.h>
-#include <libc.h>
-#include "go.h"
+typedef struct EscState EscState;
+
+static void escfunc(EscState*, Node *func);
+static void esclist(EscState*, NodeList *l);
+static void esc(EscState*, Node *n);
+static void escloopdepthlist(EscState*, NodeList *l);
+static void escloopdepth(EscState*, Node *n);
+static void escassign(EscState*, Node *dst, Node *src);
+static void esccall(EscState*, Node*);
+static void escflows(EscState*, Node *dst, Node *src);
+static void escflood(EscState*, Node *dst);
+static void escwalk(EscState*, int level, Node *dst, Node *src);
+static void esctag(EscState*, Node *func);
+
+struct EscState {
+ // Fake node that all
+ // - return values and output variables
+ // - parameters on imported functions not marked 'safe'
+ // - assignments to global variables
+ // flow to.
+ Node theSink;
+
+ NodeList* dsts; // all dst nodes
+ int loopdepth; // for detecting nested loop scopes
+ int pdepth; // for debug printing in recursions.
+ int dstcount, edgecount; // diagnostic
+ NodeList* noesc; // list of possible non-escaping nodes, for printing
+ int recursive; // recursive function or group of mutually recursive functions.
+};
+
+static Strlit *tags[16];
+
+static Strlit*
+mktag(int mask)
+{
+ Strlit *s;
+ char buf[40];
+
+ switch(mask&EscMask) {
+ case EscNone:
+ case EscReturn:
+ break;
+ default:
+ fatal("escape mktag");
+ }
-static void escfunc(Node *func);
-static void esclist(NodeList *l);
-static void esc(Node *n);
-static void escloopdepthlist(NodeList *l);
-static void escloopdepth(Node *n);
-static void escassign(Node *dst, Node *src);
-static void esccall(Node*);
-static void escflows(Node *dst, Node *src);
-static void escflood(Node *dst);
-static void escwalk(int level, Node *dst, Node *src);
-static void esctag(Node *func);
-
-// Fake node that all
-// - return values and output variables
-// - parameters on imported functions not marked 'safe'
-// - assignments to global variables
-// flow to.
-static Node theSink;
-
-static NodeList* dsts; // all dst nodes
-static int loopdepth; // for detecting nested loop scopes
-static int pdepth; // for debug printing in recursions.
-static Strlit* safetag; // gets slapped on safe parameters' field types for export
-static int dstcount, edgecount; // diagnostic
-static NodeList* noesc; // list of possible non-escaping nodes, for printing
+ mask >>= EscBits;
-void
-escapes(NodeList *all)
+ if(mask < nelem(tags) && tags[mask] != nil)
+ return tags[mask];
+
+ snprint(buf, sizeof buf, "esc:0x%x", mask);
+ s = strlit(buf);
+ if(mask < nelem(tags))
+ tags[mask] = s;
+ return s;
+}
+
+static int
+parsetag(Strlit *note)
{
- NodeList *l;
+ int em;
+
+ if(note == nil)
+ return EscUnknown;
+ if(strncmp(note->s, "esc:", 4) != 0)
+ return EscUnknown;
+ em = atoi(note->s + 4);
+ if (em == 0)
+ return EscNone;
+ return EscReturn | (em << EscBits);
+}
- theSink.op = ONAME;
- theSink.orig = &theSink;
- theSink.class = PEXTERN;
- theSink.sym = lookup(".sink");
- theSink.escloopdepth = -1;
+static void
+analyze(NodeList *all, int recursive)
+{
+ NodeList *l;
+ EscState es, *e;
+
+ memset(&es, 0, sizeof es);
+ e = &es;
+ e->theSink.op = ONAME;
+ e->theSink.orig = &e->theSink;
+ e->theSink.class = PEXTERN;
+ e->theSink.sym = lookup(".sink");
+ e->theSink.escloopdepth = -1;
+ e->recursive = recursive;
- safetag = strlit("noescape");
- noesc = nil;
+ for(l=all; l; l=l->next)
+ if(l->n->op == ODCLFUNC)
+ l->n->esc = EscFuncPlanned;
// flow-analyze functions
for(l=all; l; l=l->next)
- if(l->n->op == ODCLFUNC || l->n->op == OCLOSURE)
- escfunc(l->n);
+ if(l->n->op == ODCLFUNC)
+ escfunc(e, l->n);
- // print("escapes: %d dsts, %d edges\n", dstcount, edgecount);
+ // print("escapes: %d e->dsts, %d edges\n", e->dstcount, e->edgecount);
- // visit the updstream of each dst, mark address nodes with
+ // visit the upstream of each dst, mark address nodes with
// addrescapes, mark parameters unsafe
- for(l = dsts; l; l=l->next)
- escflood(l->n);
+ for(l = e->dsts; l; l=l->next)
+ escflood(e, l->n);
// for all top level functions, tag the typenodes corresponding to the param nodes
for(l=all; l; l=l->next)
if(l->n->op == ODCLFUNC)
- esctag(l->n);
+ esctag(e, l->n);
if(debug['m']) {
- for(l=noesc; l; l=l->next)
+ for(l=e->noesc; l; l=l->next)
if(l->n->esc == EscNone)
warnl(l->n->lineno, "%S %hN does not escape",
(l->n->curfn && l->n->curfn->nname) ? l->n->curfn->nname->sym : S,
@@ -100,14 +302,20 @@ escapes(NodeList *all)
static void
-escfunc(Node *func)
+escfunc(EscState *e, Node *func)
{
- Node *savefn, *n;
+ Node *savefn;
NodeList *ll;
int saveld;
- saveld = loopdepth;
- loopdepth = 1;
+// print("escfunc %N %s\n", func->nname, e->recursive?"(recursive)":"");
+
+ if(func->esc != 1)
+ fatal("repeat escfunc %N", func->nname);
+ func->esc = EscFuncStarted;
+
+ saveld = e->loopdepth;
+ e->loopdepth = 1;
savefn = curfn;
curfn = func;
@@ -116,63 +324,54 @@ escfunc(Node *func)
continue;
switch (ll->n->class) {
case PPARAMOUT:
- // output parameters flow to the sink
- escflows(&theSink, ll->n);
- ll->n->escloopdepth = loopdepth;
+ // out params are in a loopdepth between the sink and all local variables
+ ll->n->escloopdepth = 0;
break;
case PPARAM:
if(ll->n->type && !haspointers(ll->n->type))
break;
- ll->n->esc = EscNone; // prime for escflood later
- noesc = list(noesc, ll->n);
- ll->n->escloopdepth = loopdepth;
+ if(curfn->nbody == nil && !curfn->noescape)
+ ll->n->esc = EscHeap;
+ else
+ ll->n->esc = EscNone; // prime for escflood later
+ e->noesc = list(e->noesc, ll->n);
+ ll->n->escloopdepth = 1;
break;
}
}
- // walk will take the address of cvar->closure later and assign it to cvar.
- // linking a fake oaddr node directly to the closure handles the case
- // of the closure itself leaking. Following the flow of the value to th
- // paramref is done in escflow, because if we did that here, it would look
- // like the original is assigned out of its loop depth, whereas it's just
- // assigned to something in an inner function. A paramref itself is never
- // moved to the heap, only its original.
- for(ll=curfn->cvars; ll; ll=ll->next) {
- if(ll->n->op == OXXX) // see dcl.c:398
- continue;
-
- n = nod(OADDR, ll->n->closure, N);
- n->lineno = ll->n->lineno;
- typecheck(&n, Erv);
- escassign(curfn, n);
- }
+ // in a mutually recursive group we lose track of the return values
+ if(e->recursive)
+ for(ll=curfn->dcl; ll; ll=ll->next)
+ if(ll->n->op == ONAME && ll->n->class == PPARAMOUT)
+ escflows(e, &e->theSink, ll->n);
- escloopdepthlist(curfn->nbody);
- esclist(curfn->nbody);
+ escloopdepthlist(e, curfn->nbody);
+ esclist(e, curfn->nbody);
curfn = savefn;
- loopdepth = saveld;
+ e->loopdepth = saveld;
}
-// Mark labels that have no backjumps to them as not increasing loopdepth.
+// Mark labels that have no backjumps to them as not increasing e->loopdepth.
// Walk hasn't generated (goto|label)->left->sym->label yet, so we'll cheat
// and set it to one of the following two. Then in esc we'll clear it again.
static Label looping;
static Label nonlooping;
static void
-escloopdepthlist(NodeList *l)
+escloopdepthlist(EscState *e, NodeList *l)
{
for(; l; l=l->next)
- escloopdepth(l->n);
+ escloopdepth(e, l->n);
}
static void
-escloopdepth(Node *n)
+escloopdepth(EscState *e, Node *n)
{
if(n == N)
return;
- escloopdepthlist(n->ninit);
+ escloopdepthlist(e, n->ninit);
switch(n->op) {
case OLABEL:
@@ -194,29 +393,30 @@ escloopdepth(Node *n)
break;
}
- escloopdepth(n->left);
- escloopdepth(n->right);
- escloopdepthlist(n->list);
- escloopdepth(n->ntest);
- escloopdepth(n->nincr);
- escloopdepthlist(n->nbody);
- escloopdepthlist(n->nelse);
- escloopdepthlist(n->rlist);
+ escloopdepth(e, n->left);
+ escloopdepth(e, n->right);
+ escloopdepthlist(e, n->list);
+ escloopdepth(e, n->ntest);
+ escloopdepth(e, n->nincr);
+ escloopdepthlist(e, n->nbody);
+ escloopdepthlist(e, n->nelse);
+ escloopdepthlist(e, n->rlist);
}
static void
-esclist(NodeList *l)
+esclist(EscState *e, NodeList *l)
{
for(; l; l=l->next)
- esc(l->n);
+ esc(e, l->n);
}
static void
-esc(Node *n)
+esc(EscState *e, Node *n)
{
int lno;
NodeList *ll, *lr;
+ Node *a;
if(n == N)
return;
@@ -224,33 +424,30 @@ esc(Node *n)
lno = setlineno(n);
if(n->op == OFOR || n->op == ORANGE)
- loopdepth++;
-
- if(n->op == OCLOSURE) {
- escfunc(n);
- } else {
- esc(n->left);
- esc(n->right);
- esc(n->ntest);
- esc(n->nincr);
- esclist(n->ninit);
- esclist(n->nbody);
- esclist(n->nelse);
- esclist(n->list);
- esclist(n->rlist);
- }
+ e->loopdepth++;
+
+ esc(e, n->left);
+ esc(e, n->right);
+ esc(e, n->ntest);
+ esc(e, n->nincr);
+ esclist(e, n->ninit);
+ esclist(e, n->nbody);
+ esclist(e, n->nelse);
+ esclist(e, n->list);
+ esclist(e, n->rlist);
+
if(n->op == OFOR || n->op == ORANGE)
- loopdepth--;
+ e->loopdepth--;
if(debug['m'] > 1)
- print("%L:[%d] %S esc: %N\n", lineno, loopdepth,
+ print("%L:[%d] %S esc: %N\n", lineno, e->loopdepth,
(curfn && curfn->nname) ? curfn->nname->sym : S, n);
switch(n->op) {
case ODCL:
// Record loop depth at declaration.
if(n->left)
- n->left->escloopdepth = loopdepth;
+ n->left->escloopdepth = e->loopdepth;
break;
case OLABEL:
@@ -260,18 +457,19 @@ esc(Node *n)
} else if(n->left->sym->label == &looping) {
if(debug['m'] > 1)
print("%L: %N looping label\n", lineno, n);
- loopdepth++;
+ e->loopdepth++;
}
// See case OLABEL in escloopdepth above
// else if(n->left->sym->label == nil)
- // fatal("escape anaylysis missed or messed up a label: %+N", n);
+ // fatal("escape analysis missed or messed up a label: %+N", n);
n->left->sym->label = nil;
+ break;
case ORANGE:
// Everything but fixed array is a dereference.
if(isfixedarray(n->type) && n->list->next)
- escassign(n->list->next->n, n->right);
+ escassign(e, n->list->next->n, n->right);
break;
case OSWITCH:
@@ -279,123 +477,157 @@ esc(Node *n)
for(ll=n->list; ll; ll=ll->next) { // cases
// ntest->right is the argument of the .(type),
// ll->n->nname is the variable per case
- escassign(ll->n->nname, n->ntest->right);
+ escassign(e, ll->n->nname, n->ntest->right);
}
}
break;
case OAS:
case OASOP:
- escassign(n->left, n->right);
+ escassign(e, n->left, n->right);
break;
case OAS2: // x,y = a,b
if(count(n->list) == count(n->rlist))
for(ll=n->list, lr=n->rlist; ll; ll=ll->next, lr=lr->next)
- escassign(ll->n, lr->n);
+ escassign(e, ll->n, lr->n);
break;
case OAS2RECV: // v, ok = <-ch
case OAS2MAPR: // v, ok = m[k]
case OAS2DOTTYPE: // v, ok = x.(type)
- escassign(n->list->n, n->rlist->n);
+ escassign(e, n->list->n, n->rlist->n);
break;
case OSEND: // ch <- x
- escassign(&theSink, n->right);
+ escassign(e, &e->theSink, n->right);
break;
case ODEFER:
- if(loopdepth == 1) // top level
+ if(e->loopdepth == 1) // top level
break;
// arguments leak out of scope
// TODO: leak to a dummy node instead
// fallthrough
case OPROC:
// go f(x) - f and x escape
- escassign(&theSink, n->left->left);
- escassign(&theSink, n->left->right); // ODDDARG for call
+ escassign(e, &e->theSink, n->left->left);
+ escassign(e, &e->theSink, n->left->right); // ODDDARG for call
for(ll=n->left->list; ll; ll=ll->next)
- escassign(&theSink, ll->n);
+ escassign(e, &e->theSink, ll->n);
+ break;
+
+ case OCALLMETH:
+ case OCALLFUNC:
+ case OCALLINTER:
+ esccall(e, n);
+ break;
+
+ case OAS2FUNC: // x,y = f()
+ // esccall already done on n->rlist->n. tie it's escretval to n->list
+ lr=n->rlist->n->escretval;
+ for(ll=n->list; lr && ll; lr=lr->next, ll=ll->next)
+ escassign(e, ll->n, lr->n);
+ if(lr || ll)
+ fatal("esc oas2func");
break;
case ORETURN:
- for(ll=n->list; ll; ll=ll->next)
- escassign(&theSink, ll->n);
+ ll=n->list;
+ if(count(n->list) == 1 && curfn->type->outtuple > 1) {
+ // OAS2FUNC in disguise
+ // esccall already done on n->list->n
+ // tie n->list->n->escretval to curfn->dcl PPARAMOUT's
+ ll = n->list->n->escretval;
+ }
+
+ for(lr = curfn->dcl; lr && ll; lr=lr->next) {
+ if (lr->n->op != ONAME || lr->n->class != PPARAMOUT)
+ continue;
+ escassign(e, lr->n, ll->n);
+ ll = ll->next;
+ }
+ if (ll != nil)
+ fatal("esc return list");
break;
case OPANIC:
// Argument could leak through recover.
- escassign(&theSink, n->left);
+ escassign(e, &e->theSink, n->left);
break;
case OAPPEND:
if(!n->isddd)
for(ll=n->list->next; ll; ll=ll->next)
- escassign(&theSink, ll->n); // lose track of assign to dereference
- break;
-
- case OCALLMETH:
- case OCALLFUNC:
- case OCALLINTER:
- esccall(n);
+ escassign(e, &e->theSink, ll->n); // lose track of assign to dereference
break;
case OCONV:
case OCONVNOP:
case OCONVIFACE:
- escassign(n, n->left);
+ escassign(e, n, n->left);
break;
case OARRAYLIT:
if(isslice(n->type)) {
n->esc = EscNone; // until proven otherwise
- noesc = list(noesc, n);
- n->escloopdepth = loopdepth;
+ e->noesc = list(e->noesc, n);
+ n->escloopdepth = e->loopdepth;
// Values make it to memory, lose track.
for(ll=n->list; ll; ll=ll->next)
- escassign(&theSink, ll->n->right);
+ escassign(e, &e->theSink, ll->n->right);
} else {
// Link values to array.
for(ll=n->list; ll; ll=ll->next)
- escassign(n, ll->n->right);
+ escassign(e, n, ll->n->right);
}
break;
case OSTRUCTLIT:
// Link values to struct.
for(ll=n->list; ll; ll=ll->next)
- escassign(n, ll->n->right);
+ escassign(e, n, ll->n->right);
break;
case OPTRLIT:
n->esc = EscNone; // until proven otherwise
- noesc = list(noesc, n);
- n->escloopdepth = loopdepth;
+ e->noesc = list(e->noesc, n);
+ n->escloopdepth = e->loopdepth;
// Contents make it to memory, lose track.
- escassign(&theSink, n->left);
+ escassign(e, &e->theSink, n->left);
break;
case OMAPLIT:
n->esc = EscNone; // until proven otherwise
- noesc = list(noesc, n);
- n->escloopdepth = loopdepth;
+ e->noesc = list(e->noesc, n);
+ n->escloopdepth = e->loopdepth;
// Keys and values make it to memory, lose track.
for(ll=n->list; ll; ll=ll->next) {
- escassign(&theSink, ll->n->left);
- escassign(&theSink, ll->n->right);
+ escassign(e, &e->theSink, ll->n->left);
+ escassign(e, &e->theSink, ll->n->right);
}
break;
case OCLOSURE:
+ // Link addresses of captured variables to closure.
+ for(ll=n->cvars; ll; ll=ll->next) {
+ if(ll->n->op == OXXX) // unnamed out argument; see dcl.c:/^funcargs
+ continue;
+ a = nod(OADDR, ll->n->closure, N);
+ a->lineno = ll->n->lineno;
+ a->escloopdepth = e->loopdepth;
+ typecheck(&a, Erv);
+ escassign(e, n, a);
+ }
+ // fallthrough
case OADDR:
case OMAKECHAN:
case OMAKEMAP:
case OMAKESLICE:
case ONEW:
- n->escloopdepth = loopdepth;
+ n->escloopdepth = e->loopdepth;
n->esc = EscNone; // until proven otherwise
- noesc = list(noesc, n);
+ e->noesc = list(e->noesc, n);
break;
}
@@ -407,21 +639,22 @@ esc(Node *n)
// evaluated in curfn. For expr==nil, dst must still be examined for
// evaluations inside it (e.g *f(x) = y)
static void
-escassign(Node *dst, Node *src)
+escassign(EscState *e, Node *dst, Node *src)
{
int lno;
+ NodeList *ll;
if(isblank(dst) || dst == N || src == N || src->op == ONONAME || src->op == OXXX)
return;
if(debug['m'] > 1)
- print("%L:[%d] %S escassign: %hN(%hJ) = %hN(%hJ)\n", lineno, loopdepth,
+ print("%L:[%d] %S escassign: %hN(%hJ) = %hN(%hJ)\n", lineno, e->loopdepth,
(curfn && curfn->nname) ? curfn->nname->sym : S, dst, dst, src, src);
setlineno(dst);
// Analyze lhs of assignment.
- // Replace dst with theSink if we can't track it.
+ // Replace dst with e->theSink if we can't track it.
switch(dst->op) {
default:
dump("dst", dst);
@@ -438,31 +671,31 @@ escassign(Node *dst, Node *src)
case ONAME:
if(dst->class == PEXTERN)
- dst = &theSink;
+ dst = &e->theSink;
break;
case ODOT: // treat "dst.x = src" as "dst = src"
- escassign(dst->left, src);
+ escassign(e, dst->left, src);
return;
case OINDEX:
if(isfixedarray(dst->left->type)) {
- escassign(dst->left, src);
+ escassign(e, dst->left, src);
return;
}
- dst = &theSink; // lose track of dereference
+ dst = &e->theSink; // lose track of dereference
break;
case OIND:
case ODOTPTR:
- dst = &theSink; // lose track of dereference
+ dst = &e->theSink; // lose track of dereference
break;
case OINDEXMAP:
// lose track of key and value
- escassign(&theSink, dst->right);
- dst = &theSink;
+ escassign(e, &e->theSink, dst->right);
+ dst = &e->theSink;
break;
}
lno = setlineno(src);
- pdepth++;
+ e->pdepth++;
switch(src->op) {
case OADDR: // dst = &x
@@ -480,7 +713,16 @@ escassign(Node *dst, Node *src)
case OMAKESLICE:
case ONEW:
case OCLOSURE:
- escflows(dst, src);
+ escflows(e, dst, src);
+ break;
+
+ case OCALLMETH:
+ case OCALLFUNC:
+ case OCALLINTER:
+ // Flowing multiple returns to a single dst happens when
+ // analyzing "go f(g())": here g() flows to sink (issue 4529).
+ for(ll=src->escretval; ll; ll=ll->next)
+ escflows(e, dst, ll->n);
break;
case ODOT:
@@ -498,18 +740,18 @@ escassign(Node *dst, Node *src)
case OSLICE:
case OSLICEARR:
// Conversions, field access, slice all preserve the input value.
- escassign(dst, src->left);
+ escassign(e, dst, src->left);
break;
case OAPPEND:
// Append returns first argument.
- escassign(dst, src->list->n);
+ escassign(e, dst, src->list->n);
break;
case OINDEX:
// Index of array preserves input value.
if(isfixedarray(src->left->type))
- escassign(dst, src->left);
+ escassign(e, dst, src->left);
break;
case OADD:
@@ -529,29 +771,49 @@ escassign(Node *dst, Node *src)
// Might be pointer arithmetic, in which case
// the operands flow into the result.
// TODO(rsc): Decide what the story is here. This is unsettling.
- escassign(dst, src->left);
- escassign(dst, src->right);
+ escassign(e, dst, src->left);
+ escassign(e, dst, src->right);
break;
-
}
- pdepth--;
+ e->pdepth--;
lineno = lno;
}
+static void
+escassignfromtag(EscState *e, Strlit *note, NodeList *dsts, Node *src)
+{
+ int em;
+
+ em = parsetag(note);
+
+ if(em == EscUnknown) {
+ escassign(e, &e->theSink, src);
+ return;
+ }
+
+ for(em >>= EscBits; em && dsts; em >>= 1, dsts=dsts->next)
+ if(em & 1)
+ escassign(e, dsts->n, src);
+
+ if (em != 0 && dsts == nil)
+ fatal("corrupt esc tag %Z or messed up escretval list\n", note);
+}
-// This is a bit messier than fortunate, pulled out of escassign's big
+// This is a bit messier than fortunate, pulled out of esc's big
// switch for clarity. We either have the paramnodes, which may be
-// connected to other things throug flows or we have the parameter type
+// connected to other things through flows or we have the parameter type
// nodes, which may be marked "noescape". Navigating the ast is slightly
// different for methods vs plain functions and for imported vs
// this-package
static void
-esccall(Node *n)
+esccall(EscState *e, Node *n)
{
NodeList *ll, *lr;
Node *a, *fn, *src;
Type *t, *fntype;
+ char buf[40];
+ int i;
fn = N;
switch(n->op) {
@@ -579,74 +841,96 @@ esccall(Node *n)
ll = n->list;
if(n->list != nil && n->list->next == nil) {
a = n->list->n;
- if(a->type->etype == TSTRUCT && a->type->funarg) {
- // f(g()).
- // Since f's arguments are g's results and
- // all function results escape, we're done.
- ll = nil;
- }
+ if(a->type->etype == TSTRUCT && a->type->funarg) // f(g()).
+ ll = a->escretval;
}
- if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody && fn->ntype) {
- // Local function. Incorporate into flow graph.
+ if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody && fn->ntype && fn->defn->esc < EscFuncTagged) {
+ // function in same mutually recursive group. Incorporate into flow graph.
+// print("esc local fn: %N\n", fn->ntype);
+ if(fn->defn->esc == EscFuncUnknown || n->escretval != nil)
+ fatal("graph inconsistency");
+
+ // set up out list on this call node
+ for(lr=fn->ntype->rlist; lr; lr=lr->next)
+ n->escretval = list(n->escretval, lr->n->left); // type.rlist -> dclfield -> ONAME (PPARAMOUT)
// Receiver.
if(n->op != OCALLFUNC)
- escassign(fn->ntype->left->left, n->left->left);
+ escassign(e, fn->ntype->left->left, n->left->left);
for(lr=fn->ntype->list; ll && lr; ll=ll->next, lr=lr->next) {
src = ll->n;
if(lr->n->isddd && !n->isddd) {
// Introduce ODDDARG node to represent ... allocation.
src = nod(ODDDARG, N, N);
- src->escloopdepth = loopdepth;
+ src->escloopdepth = e->loopdepth;
src->lineno = n->lineno;
src->esc = EscNone; // until we find otherwise
- noesc = list(noesc, src);
+ e->noesc = list(e->noesc, src);
n->right = src;
}
if(lr->n->left != N)
- escassign(lr->n->left, src);
+ escassign(e, lr->n->left, src);
if(src != ll->n)
break;
}
// "..." arguments are untracked
for(; ll; ll=ll->next)
- escassign(&theSink, ll->n);
+ escassign(e, &e->theSink, ll->n);
+
return;
}
- // Imported function. Use the escape tags.
- if(n->op != OCALLFUNC) {
- t = getthisx(fntype)->type;
- if(!t->note || strcmp(t->note->s, safetag->s) != 0)
- escassign(&theSink, n->left->left);
+ // Imported or completely analyzed function. Use the escape tags.
+ if(n->escretval != nil)
+ fatal("esc already decorated call %+N\n", n);
+
+ // set up out list on this call node with dummy auto ONAMES in the current (calling) function.
+ i = 0;
+ for(t=getoutargx(fntype)->type; t; t=t->down) {
+ src = nod(ONAME, N, N);
+ snprint(buf, sizeof buf, ".dum%d", i++);
+ src->sym = lookup(buf);
+ src->type = t->type;
+ src->class = PAUTO;
+ src->curfn = curfn;
+ src->escloopdepth = e->loopdepth;
+ src->used = 1;
+ src->lineno = n->lineno;
+ n->escretval = list(n->escretval, src);
}
+
+// print("esc analyzed fn: %#N (%+T) returning (%+H)\n", fn, fntype, n->escretval);
+
+ // Receiver.
+ if(n->op != OCALLFUNC)
+ escassignfromtag(e, getthisx(fntype)->type->note, n->escretval, n->left->left);
+
for(t=getinargx(fntype)->type; ll; ll=ll->next) {
src = ll->n;
if(t->isddd && !n->isddd) {
// Introduce ODDDARG node to represent ... allocation.
src = nod(ODDDARG, N, N);
- src->escloopdepth = loopdepth;
+ src->escloopdepth = e->loopdepth;
src->lineno = n->lineno;
src->esc = EscNone; // until we find otherwise
- noesc = list(noesc, src);
+ e->noesc = list(e->noesc, src);
n->right = src;
}
- if(!t->note || strcmp(t->note->s, safetag->s) != 0)
- escassign(&theSink, src);
+ escassignfromtag(e, t->note, n->escretval, src);
if(src != ll->n)
break;
t = t->down;
}
// "..." arguments are untracked
for(; ll; ll=ll->next)
- escassign(&theSink, ll->n);
+ escassign(e, &e->theSink, ll->n);
}
// Store the link src->dst in dst, throwing out some quick wins.
static void
-escflows(Node *dst, Node *src)
+escflows(EscState *e, Node *dst, Node *src)
{
if(dst == nil || src == nil || dst == src)
return;
@@ -659,10 +943,10 @@ escflows(Node *dst, Node *src)
print("%L::flows:: %hN <- %hN\n", lineno, dst, src);
if(dst->escflowsrc == nil) {
- dsts = list(dsts, dst);
- dstcount++;
+ e->dsts = list(e->dsts, dst);
+ e->dstcount++;
}
- edgecount++;
+ e->edgecount++;
dst->escflowsrc = list(dst->escflowsrc, src);
}
@@ -673,11 +957,11 @@ escflows(Node *dst, Node *src)
// so this address doesn't leak (yet).
// If level == 0, it means the /value/ of this node can reach the root of this flood.
// so if this node is an OADDR, it's argument should be marked as escaping iff
-// it's currfn/loopdepth are different from the flood's root.
+// it's currfn/e->loopdepth are different from the flood's root.
// Once an object has been moved to the heap, all of it's upstream should be considered
// escaping to the global scope.
static void
-escflood(Node *dst)
+escflood(EscState *e, Node *dst)
{
NodeList *l;
@@ -696,45 +980,71 @@ escflood(Node *dst)
for(l = dst->escflowsrc; l; l=l->next) {
walkgen++;
- escwalk(0, dst, l->n);
+ escwalk(e, 0, dst, l->n);
}
}
+// There appear to be some loops in the escape graph, causing
+// arbitrary recursion into deeper and deeper levels.
+// Cut this off safely by making minLevel sticky: once you
+// get that deep, you cannot go down any further but you also
+// cannot go up any further. This is a conservative fix.
+// Making minLevel smaller (more negative) would handle more
+// complex chains of indirections followed by address-of operations,
+// at the cost of repeating the traversal once for each additional
+// allowed level when a loop is encountered. Using -2 suffices to
+// pass all the tests we have written so far, which we assume matches
+// the level of complexity we want the escape analysis code to handle.
+#define MinLevel (-2)
+
static void
-escwalk(int level, Node *dst, Node *src)
+escwalk(EscState *e, int level, Node *dst, Node *src)
{
NodeList *ll;
- int leaks;
+ int leaks, newlevel;
- if(src->walkgen == walkgen)
+ if(src->walkgen == walkgen && src->esclevel <= level)
return;
src->walkgen = walkgen;
+ src->esclevel = level;
if(debug['m']>1)
print("escwalk: level:%d depth:%d %.*s %hN(%hJ) scope:%S[%d]\n",
- level, pdepth, pdepth, "\t\t\t\t\t\t\t\t\t\t", src, src,
+ level, e->pdepth, e->pdepth, "\t\t\t\t\t\t\t\t\t\t", src, src,
(src->curfn && src->curfn->nname) ? src->curfn->nname->sym : S, src->escloopdepth);
- pdepth++;
+ e->pdepth++;
+
+ // Input parameter flowing to output parameter?
+ if(dst->op == ONAME && dst->class == PPARAMOUT && dst->vargen <= 20) {
+ if(src->op == ONAME && src->class == PPARAM && level == 0 && src->curfn == dst->curfn) {
+ if(src->esc != EscScope && src->esc != EscHeap) {
+ if(debug['m'])
+ warnl(src->lineno, "leaking param: %hN to result %S", src, dst->sym);
+ if((src->esc&EscMask) != EscReturn)
+ src->esc = EscReturn;
+ src->esc |= 1<<((dst->vargen-1) + EscBits);
+ goto recurse;
+ }
+ }
+ }
leaks = (level <= 0) && (dst->escloopdepth < src->escloopdepth);
switch(src->op) {
case ONAME:
- if(src->class == PPARAM && leaks && src->esc == EscNone) {
+ if(src->class == PPARAM && leaks && src->esc != EscHeap) {
src->esc = EscScope;
if(debug['m'])
warnl(src->lineno, "leaking param: %hN", src);
}
- // handle the missing flow ref <- orig
- // a paramref is automagically dereferenced, and taking its
- // address produces the address of the original, so all we have to do here
- // is keep track of the value flow, so level is unchanged.
- // alternatively, we could have substituted PPARAMREFs with their ->closure in esc/escassign/flow,
+
+ // Treat a PPARAMREF closure variable as equivalent to the
+ // original variable.
if(src->class == PPARAMREF) {
if(leaks && debug['m'])
warnl(src->lineno, "leaking closure reference %hN", src);
- escwalk(level, dst, src->closure);
+ escwalk(e, level, dst, src->closure);
}
break;
@@ -746,7 +1056,10 @@ escwalk(int level, Node *dst, Node *src)
if(debug['m'])
warnl(src->lineno, "%hN escapes to heap", src);
}
- escwalk(level-1, dst, src->left);
+ newlevel = level;
+ if(level > MinLevel)
+ newlevel--;
+ escwalk(e, newlevel, dst, src->left);
break;
case OARRAYLIT:
@@ -767,32 +1080,53 @@ escwalk(int level, Node *dst, Node *src)
}
break;
+ case ODOT:
+ escwalk(e, level, dst, src->left);
+ break;
+
case OINDEX:
- if(isfixedarray(src->type))
+ if(isfixedarray(src->left->type)) {
+ escwalk(e, level, dst, src->left);
break;
+ }
// fall through
case OSLICE:
case ODOTPTR:
case OINDEXMAP:
case OIND:
- escwalk(level+1, dst, src->left);
+ newlevel = level;
+ if(level > MinLevel)
+ newlevel++;
+ escwalk(e, newlevel, dst, src->left);
}
+recurse:
for(ll=src->escflowsrc; ll; ll=ll->next)
- escwalk(level, dst, ll->n);
+ escwalk(e, level, dst, ll->n);
- pdepth--;
+ e->pdepth--;
}
static void
-esctag(Node *func)
+esctag(EscState *e, Node *func)
{
Node *savefn;
NodeList *ll;
+ Type *t;
+
+ USED(e);
+ func->esc = EscFuncTagged;
- // External functions must be assumed unsafe.
- if(func->nbody == nil)
+ // External functions are assumed unsafe,
+ // unless //go:noescape is given before the declaration.
+ if(func->nbody == nil) {
+ if(func->noescape) {
+ for(t=getinargx(func->type)->type; t; t=t->down)
+ if(haspointers(t->type))
+ t->note = mktag(EscNone);
+ }
return;
+ }
savefn = curfn;
curfn = func;
@@ -801,10 +1135,12 @@ esctag(Node *func)
if(ll->n->op != ONAME || ll->n->class != PPARAM)
continue;
- switch (ll->n->esc) {
+ switch (ll->n->esc&EscMask) {
case EscNone: // not touched by escflood
+ case EscReturn:
if(haspointers(ll->n->type)) // don't bother tagging for scalars
- ll->n->paramfld->note = safetag;
+ ll->n->paramfld->note = mktag(ll->n->esc);
+ break;
case EscHeap: // touched by escflood, moved to heap
case EscScope: // touched by escflood, value leaves scope
break;
diff --git a/src/cmd/gc/export.c b/src/cmd/gc/export.c
index bbed8ae36..b7311665a 100644
--- a/src/cmd/gc/export.c
+++ b/src/cmd/gc/export.c
@@ -22,22 +22,8 @@ exportsym(Node *n)
}
n->sym->flags |= SymExport;
- exportlist = list(exportlist, n);
-}
-
-// Mark n's symbol as package-local
-static void
-packagesym(Node *n)
-{
- if(n == N || n->sym == S)
- return;
- if(n->sym->flags & (SymExport|SymPackage)) {
- if(n->sym->flags & SymExport)
- yyerror("export/package mismatch: %S", n->sym);
- return;
- }
- n->sym->flags |= SymPackage;
-
+ if(debug['E'])
+ print("export symbol %S\n", n->sym);
exportlist = list(exportlist, n);
}
@@ -58,6 +44,18 @@ initname(char *s)
return strcmp(s, "init") == 0;
}
+// exportedsym returns whether a symbol will be visible
+// to files that import our package.
+static int
+exportedsym(Sym *sym)
+{
+ // Builtins are visible everywhere.
+ if(sym->pkg == builtinpkg || sym->origpkg == builtinpkg)
+ return 1;
+
+ return sym->pkg == localpkg && exportname(sym->name);
+}
+
void
autoexport(Node *n, int ctxt)
{
@@ -67,10 +65,9 @@ autoexport(Node *n, int ctxt)
return;
if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left) // method
return;
- if(exportname(n->sym->name) || initname(n->sym->name))
+ // -A is for cmd/gc/mkbuiltin script, so export everything
+ if(debug['A'] || exportname(n->sym->name) || initname(n->sym->name))
exportsym(n);
- else
- packagesym(n);
}
static void
@@ -104,36 +101,60 @@ reexportdep(Node *n)
if(!n)
return;
-// print("reexportdep %+hN\n", n);
+ //print("reexportdep %+hN\n", n);
switch(n->op) {
case ONAME:
switch(n->class&~PHEAP) {
case PFUNC:
// methods will be printed along with their type
+ // nodes for T.Method expressions
+ if(n->left && n->left->op == OTYPE)
+ break;
+ // nodes for method calls.
if(!n->type || n->type->thistuple > 0)
break;
// fallthrough
case PEXTERN:
- if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg)
+ if(n->sym && !exportedsym(n->sym)) {
+ if(debug['E'])
+ print("reexport name %S\n", n->sym);
exportlist = list(exportlist, n);
+ }
}
break;
+ case ODCL:
+ // Local variables in the bodies need their type.
+ t = n->left->type;
+ if(t != types[t->etype] && t != idealbool && t != idealstring) {
+ if(isptr[t->etype])
+ t = t->type;
+ if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+ if(debug['E'])
+ print("reexport type %S from declaration\n", t->sym);
+ exportlist = list(exportlist, t->sym->def);
+ }
+ }
+ break;
case OLITERAL:
t = n->type;
if(t != types[n->type->etype] && t != idealbool && t != idealstring) {
if(isptr[t->etype])
t = t->type;
- if (t && t->sym && t->sym->def && t->sym->pkg != localpkg && t->sym->pkg != builtinpkg) {
-// print("reexport literal type %+hN\n", t->sym->def);
+ if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+ if(debug['E'])
+ print("reexport literal type %S\n", t->sym);
exportlist = list(exportlist, t->sym->def);
}
}
// fallthrough
case OTYPE:
- if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg)
+ if(n->sym && !exportedsym(n->sym)) {
+ if(debug['E'])
+ print("reexport literal/type %S\n", n->sym);
exportlist = list(exportlist, n);
+ }
break;
// for operations that need a type when rendered, put the type on the export list.
@@ -141,13 +162,15 @@ reexportdep(Node *n)
case OCONVIFACE:
case OCONVNOP:
case ODOTTYPE:
+ case ODOTTYPE2:
case OSTRUCTLIT:
case OPTRLIT:
t = n->type;
if(!t->sym && t->type)
t = t->type;
- if (t && t->sym && t->sym->def && t->sym->pkg != localpkg && t->sym->pkg != builtinpkg) {
-// print("reexport convnop %+hN\n", t->sym->def);
+ if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+ if(debug['E'])
+ print("reexport type for convnop %S\n", t->sym);
exportlist = list(exportlist, t->sym->def);
}
break;
@@ -207,10 +230,11 @@ dumpexportvar(Sym *s)
// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
if(debug['l'] < 2)
typecheckinl(n);
- Bprint(bout, "\tfunc %#S%#hT { %#H }\n", s, t, n->inl);
+ // NOTE: The space after %#S here is necessary for ld's export data parser.
+ Bprint(bout, "\tfunc %#S %#hT { %#H }\n", s, t, n->inl);
reexportdeplist(n->inl);
} else
- Bprint(bout, "\tfunc %#S%#hT\n", s, t);
+ Bprint(bout, "\tfunc %#S %#hT\n", s, t);
} else
Bprint(bout, "\tvar %#S %#T\n", s, t);
}
@@ -262,15 +286,17 @@ dumpexporttype(Type *t)
Bprint(bout, "\ttype %#S %#lT\n", t->sym, t);
for(i=0; i<n; i++) {
f = m[i];
+ if(f->nointerface)
+ Bprint(bout, "\t//go:nointerface\n");
if (f->type->nname && f->type->nname->inl) { // nname was set by caninl
// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
if(debug['l'] < 2)
typecheckinl(f->type->nname);
- Bprint(bout, "\tfunc (%#T) %#hhS%#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl);
+ Bprint(bout, "\tfunc (%#T) %#hhS %#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl);
reexportdeplist(f->type->nname->inl);
} else
- Bprint(bout, "\tfunc (%#T) %#hhS%#hT\n", getthisx(f->type)->type, f->sym, f->type);
+ Bprint(bout, "\tfunc (%#T) %#hhS %#hT\n", getthisx(f->type)->type, f->sym, f->type);
}
}
@@ -349,8 +375,12 @@ dumpexport(void)
Sym*
importsym(Sym *s, int op)
{
- if(s->def != N && s->def->op != op)
- redeclare(s, "during import");
+ char *pkgstr;
+
+ if(s->def != N && s->def->op != op) {
+ pkgstr = smprint("during import \"%Z\"", importpkg->path);
+ redeclare(s, pkgstr);
+ }
// mark the symbol so it is not reexported
if(s->def == N) {
@@ -389,6 +419,8 @@ importimport(Sym *s, Strlit *z)
// human-readable messages.
Pkg *p;
+ if(isbadimport(z))
+ errorexit();
p = mkpkg(z);
if(p->name == nil) {
p->name = s->name;
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);
}
diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c
index 96e7b526c..5f03d9476 100644
--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -266,6 +266,8 @@ gen(Node *n)
Label *lab;
int32 wasregalloc;
+//dump("gen", n);
+
lno = setlineno(n);
wasregalloc = anyregalloc();
@@ -279,7 +281,7 @@ gen(Node *n)
switch(n->op) {
default:
- fatal("gen: unknown op %N", n);
+ fatal("gen: unknown op %+hN", n);
break;
case OCASE:
@@ -394,7 +396,7 @@ gen(Node *n)
}
gen(n->nincr); // contin: incr
patch(p1, pc); // test:
- bgen(n->ntest, 0, breakpc); // if(!test) goto break
+ bgen(n->ntest, 0, -1, breakpc); // if(!test) goto break
genlist(n->nbody); // body
gjmp(continpc);
patch(breakpc, pc); // done:
@@ -410,7 +412,7 @@ gen(Node *n)
p1 = gjmp(P); // goto test
p2 = gjmp(P); // p2: goto else
patch(p1, pc); // test:
- bgen(n->ntest, 0, p2); // if(!test) goto p2
+ bgen(n->ntest, 0, -n->likely, p2); // if(!test) goto p2
genlist(n->nbody); // then
p3 = gjmp(P); // goto done
patch(p2, pc); // else:
@@ -509,22 +511,24 @@ ret:
void
cgen_callmeth(Node *n, int proc)
{
+ Node n2;
Node *l;
- // generate a rewrite for method call
+ // generate a rewrite in n2 for the method call
// (p.f)(...) goes to (f)(p,...)
l = n->left;
if(l->op != ODOTMETH)
fatal("cgen_callmeth: not dotmethod: %N");
- n->op = OCALLFUNC;
- n->left = n->left->right;
- n->left->type = l->type;
+ n2 = *n;
+ n2.op = OCALLFUNC;
+ n2.left = l->right;
+ n2.left->type = l->type;
- if(n->left->op == ONAME)
- n->left->class = PFUNC;
- cgen_call(n, proc);
+ if(n2.left->op == ONAME)
+ n2.left->class = PFUNC;
+ cgen_call(&n2, proc);
}
/*
@@ -631,6 +635,67 @@ cgen_discard(Node *nr)
}
/*
+ * clearslim generates code to zero a slim node.
+ */
+void
+clearslim(Node *n)
+{
+ Node z;
+ Mpflt zero;
+
+ memset(&z, 0, sizeof(z));
+ z.op = OLITERAL;
+ z.type = n->type;
+ z.addable = 1;
+
+ switch(simtype[n->type->etype]) {
+ case TCOMPLEX64:
+ case TCOMPLEX128:
+ z.val.u.cval = mal(sizeof(*z.val.u.cval));
+ mpmovecflt(&z.val.u.cval->real, 0.0);
+ mpmovecflt(&z.val.u.cval->imag, 0.0);
+ break;
+
+ case TFLOAT32:
+ case TFLOAT64:
+ mpmovecflt(&zero, 0.0);
+ z.val.ctype = CTFLT;
+ z.val.u.fval = &zero;
+ break;
+
+ case TPTR32:
+ case TPTR64:
+ case TCHAN:
+ case TMAP:
+ z.val.ctype = CTNIL;
+ break;
+
+ case TBOOL:
+ z.val.ctype = CTBOOL;
+ break;
+
+ case TINT8:
+ case TINT16:
+ case TINT32:
+ case TINT64:
+ case TUINT8:
+ case TUINT16:
+ case TUINT32:
+ case TUINT64:
+ z.val.ctype = CTINT;
+ z.val.u.xval = mal(sizeof(*z.val.u.xval));
+ mpmovecfix(z.val.u.xval, 0);
+ break;
+
+ default:
+ fatal("clearslim called on type %T", n->type);
+ }
+
+ ullmancalc(&z);
+ cgen(&z, n);
+}
+
+/*
* generate assignment:
* nl = nr
* nr == N means zero nl.
@@ -638,9 +703,7 @@ cgen_discard(Node *nr)
void
cgen_as(Node *nl, Node *nr)
{
- Node nc;
Type *tl;
- int iszer;
if(debug['g']) {
dump("cgen_as", nl);
@@ -655,7 +718,6 @@ cgen_as(Node *nl, Node *nr)
return;
}
- iszer = 0;
if(nr == N || isnil(nr)) {
// externals and heaps should already be clear
if(nr == N) {
@@ -670,59 +732,10 @@ cgen_as(Node *nl, Node *nr)
return;
if(isfat(tl)) {
clearfat(nl);
- goto ret;
- }
-
- /* invent a "zero" for the rhs */
- iszer = 1;
- nr = &nc;
- memset(nr, 0, sizeof(*nr));
- switch(simtype[tl->etype]) {
- default:
- fatal("cgen_as: tl %T", tl);
- break;
-
- case TINT8:
- case TUINT8:
- case TINT16:
- case TUINT16:
- case TINT32:
- case TUINT32:
- case TINT64:
- case TUINT64:
- nr->val.u.xval = mal(sizeof(*nr->val.u.xval));
- mpmovecfix(nr->val.u.xval, 0);
- nr->val.ctype = CTINT;
- break;
-
- case TFLOAT32:
- case TFLOAT64:
- nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
- mpmovecflt(nr->val.u.fval, 0.0);
- nr->val.ctype = CTFLT;
- break;
-
- case TBOOL:
- nr->val.u.bval = 0;
- nr->val.ctype = CTBOOL;
- break;
-
- case TPTR32:
- case TPTR64:
- nr->val.ctype = CTNIL;
- break;
-
- case TCOMPLEX64:
- case TCOMPLEX128:
- nr->val.u.cval = mal(sizeof(*nr->val.u.cval));
- mpmovecflt(&nr->val.u.cval->real, 0.0);
- mpmovecflt(&nr->val.u.cval->imag, 0.0);
- break;
+ return;
}
- nr->op = OLITERAL;
- nr->type = tl;
- nr->addable = 1;
- ullmancalc(nr);
+ clearslim(nl);
+ return;
}
tl = nl->type;
@@ -730,11 +743,88 @@ cgen_as(Node *nl, Node *nr)
return;
cgen(nr, nl);
- if(iszer && nl->addable)
- gused(nl);
+}
-ret:
- ;
+/*
+ * generate:
+ * res = iface{typ, data}
+ * n->left is typ
+ * n->right is data
+ */
+void
+cgen_eface(Node *n, Node *res)
+{
+ /*
+ * the right node of an eface may contain function calls that uses res as an argument,
+ * so it's important that it is done first
+ */
+ Node dst;
+ dst = *res;
+ dst.type = types[tptr];
+ dst.xoffset += widthptr;
+ cgen(n->right, &dst);
+ dst.xoffset -= widthptr;
+ cgen(n->left, &dst);
+}
+
+/*
+ * generate:
+ * res = s[lo, hi];
+ * n->left is s
+ * n->list is (cap(s)-lo(TUINT), hi-lo(TUINT)[, lo*width(TUINTPTR)])
+ * caller (cgen) guarantees res is an addable ONAME.
+ */
+void
+cgen_slice(Node *n, Node *res)
+{
+ Node src, dst, *cap, *len, *offs, *add;
+
+ cap = n->list->n;
+ len = n->list->next->n;
+ offs = N;
+ if(n->list->next->next)
+ offs = n->list->next->next->n;
+
+ // dst.len = hi [ - lo ]
+ dst = *res;
+ dst.xoffset += Array_nel;
+ dst.type = types[simtype[TUINT]];
+ cgen(len, &dst);
+
+ if(n->op != OSLICESTR) {
+ // dst.cap = cap [ - lo ]
+ dst = *res;
+ dst.xoffset += Array_cap;
+ dst.type = types[simtype[TUINT]];
+ cgen(cap, &dst);
+ }
+
+ // dst.array = src.array [ + lo *width ]
+ dst = *res;
+ dst.xoffset += Array_array;
+ dst.type = types[TUINTPTR];
+
+ if(n->op == OSLICEARR) {
+ if(!isptr[n->left->type->etype])
+ fatal("slicearr is supposed to work on pointer: %+N\n", n);
+ checkref(n->left);
+ }
+
+ if(isnil(n->left)) {
+ tempname(&src, n->left->type);
+ cgen(n->left, &src);
+ } else
+ src = *n->left;
+ src.xoffset += Array_array;
+ src.type = types[TUINTPTR];
+
+ if(offs == N) {
+ cgen(&src, &dst);
+ } else {
+ add = nod(OADD, &src, offs);
+ typecheck(&add, Erv);
+ cgen(add, &dst);
+ }
}
/*
diff --git a/src/cmd/gc/go.errors b/src/cmd/gc/go.errors
index e29cfff5b..68a5e5af3 100644
--- a/src/cmd/gc/go.errors
+++ b/src/cmd/gc/go.errors
@@ -65,6 +65,9 @@ static struct {
% loadsys package imports LVAR LNAME '=' LNAME '{' LNAME ';'
"need trailing comma before newline in composite literal",
+ % loadsys package imports LVAR LNAME '=' comptype '{' LNAME ';'
+ "need trailing comma before newline in composite literal",
+
% loadsys package imports LFUNC LNAME '(' ')' '{' LFUNC LNAME
"nested func not allowed",
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 43bd68793..f86c152f2 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -137,6 +137,7 @@ typedef struct Label Label;
struct Type
{
uchar etype;
+ uchar nointerface;
uchar chan;
uchar trecur; // to detect loops
uchar printed;
@@ -146,7 +147,7 @@ struct Type
uchar copyany;
uchar local; // created in this file
uchar deferwidth;
- uchar broke;
+ uchar broke; // broken type definition.
uchar isddd; // TFIELD is ... argument
uchar align;
@@ -170,21 +171,25 @@ struct Type
vlong argwid;
// most nodes
- Type* type;
- vlong width; // offset in TFIELD, width in all others
+ Type* type; // actual type for TFIELD, element type for TARRAY, TCHAN, TMAP, TPTRxx
+ vlong width; // offset in TFIELD, width in all others
// TFIELD
- Type* down; // also used in TMAP
+ Type* down; // next struct field, also key type in TMAP
+ Type* outer; // outer struct
Strlit* note; // literal string annotation
// TARRAY
- int32 bound; // negative is dynamic array
+ vlong bound; // negative is dynamic array
int32 maplineno; // first use of TFORW as map key
int32 embedlineno; // first use of TFORW as embedded type
// for TFORW, where to copy the eventual value to
NodeList *copyto;
+
+ // for usefield
+ Node *lastfn;
};
#define T ((Type*)0)
@@ -215,7 +220,10 @@ enum
EscHeap,
EscScope,
EscNone,
+ EscReturn,
EscNever,
+ EscBits = 4,
+ EscMask = (1<<EscBits) - 1,
};
struct Node
@@ -233,16 +241,19 @@ struct Node
NodeList* rlist;
uchar op;
+ uchar nointerface;
uchar ullman; // sethi/ullman number
uchar addable; // type of addressability - 0 is not addressable
uchar trecur; // to detect loops
uchar etype; // op for OASOP, etype for OTYPE, exclam for export
+ uchar bounded; // bounds check unnecessary
uchar class; // PPARAM, PAUTO, PEXTERN, etc
uchar method; // OCALLMETH name
uchar embedded; // ODCLFIELD embedded type
uchar colas; // OAS resulting from :=
uchar diag; // already printed error about this
uchar esc; // EscXXX
+ uchar noescape; // func arguments do not escape
uchar funcdepth;
uchar builtin; // built-in name, like len or close
uchar walkdef;
@@ -256,10 +267,10 @@ struct Node
uchar implicit;
uchar addrtaken; // address taken, even if not moved to heap
uchar dupok; // duplicate definitions ok (for func)
+ schar likely; // likeliness of if statement
// most nodes
Type* type;
- Type* realtype; // as determined by typecheck
Node* orig; // original form, for printing, and tracking copies of ONAMEs
// func
@@ -279,7 +290,7 @@ struct Node
Node* defn; // ONAME: initializing assignment; OLABEL: labeled statement
Node* pack; // real package for import . names
Node* curfn; // function for local variables
- Type* paramfld; // TFIELD for this PPARAM
+ Type* paramfld; // TFIELD for this PPARAM; also for ODOT, curfn
// ONAME func param with PHEAP
Node* heapaddr; // temp holding heap address of param
@@ -301,17 +312,19 @@ struct Node
// Escape analysis.
NodeList* escflowsrc; // flow(this, src)
- int escloopdepth; // -1: global, 0: not set, function top level:1, increased inside function for every loop or label to mark scopes
+ NodeList* escretval; // on OCALLxxx, list of dummy return values
+ int escloopdepth; // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
Sym* sym; // various
int32 vargen; // unique name for OTYPE/ONAME
int32 lineno;
int32 endlineno;
vlong xoffset;
- int32 stkdelta; // offset added by stack frame compaction phase.
+ vlong stkdelta; // offset added by stack frame compaction phase.
int32 ostk;
int32 iota;
uint32 walkgen;
+ int32 esclevel;
};
#define N ((Node*)0)
@@ -345,6 +358,7 @@ enum
SymExported = 1<<2, // already written out by export
SymUniq = 1<<3,
SymSiggen = 1<<4,
+ SymGcgen = 1<<5,
};
struct Sym
@@ -362,6 +376,7 @@ struct Sym
Label* label; // corresponding label (ephemeral)
int32 block; // blocknumber to catch redeclaration
int32 lastlineno; // last declaration for diagnostic
+ Pkg* origpkg; // original package for . import
};
#define S ((Sym*)0)
@@ -374,6 +389,7 @@ struct Pkg
Sym* pathsym;
char* prefix; // escaped path for use in symbol table
Pkg* link;
+ uchar imported; // export data of this package was parsed
char exported; // import line written in export data
char direct; // imported directly
};
@@ -398,102 +414,171 @@ struct Hist
};
#define H ((Hist*)0)
+// Node ops.
enum
{
OXXX,
// names
- ONAME,
- ONONAME,
- OTYPE,
- OPACK,
- OLITERAL,
-
- // exprs
- OADD, OSUB, OOR, OXOR, OADDSTR,
- OADDR,
- OANDAND,
- OAPPEND,
- OARRAYBYTESTR, OARRAYRUNESTR,
- OSTRARRAYBYTE, OSTRARRAYRUNE,
- OAS, OAS2, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE,
- OASOP,
- OBAD,
- OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
- OCAP,
- OCLOSE,
- OCLOSURE,
- OCMPIFACE, OCMPSTR,
- OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT, OPTRLIT,
- OCONV, OCONVIFACE, OCONVNOP,
- OCOPY,
- ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
- ODELETE,
- ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
- ODOTTYPE,
- ODOTTYPE2,
- OEQ, ONE, OLT, OLE, OGE, OGT,
- OIND,
- OINDEX, OINDEXMAP,
- OKEY, OPARAM,
- OLEN,
- OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,
- OHMUL, ORRC, OLRC, // high-mul and rotate-carry
- OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT,
- ONEW,
- ONOT, OCOM, OPLUS, OMINUS,
- OOROR,
- OPANIC, OPRINT, OPRINTN,
- OPAREN,
- OSEND,
- OSLICE, OSLICEARR, OSLICESTR,
- ORECOVER,
- ORECV,
- ORUNESTR,
- OSELRECV,
- OSELRECV2,
- OIOTA,
- OREAL, OIMAG, OCOMPLEX,
-
- // stmts
- OBLOCK,
- OBREAK,
- OCASE, OXCASE,
- OCONTINUE,
- ODEFER,
- OEMPTY,
- OFALL, OXFALL,
- OFOR,
- OGOTO,
- OIF,
- OLABEL,
- OPROC,
- ORANGE,
- ORETURN,
- OSELECT,
- OSWITCH,
- OTYPESW, // l = r.(type)
+ ONAME, // var, const or func name
+ ONONAME, // unnamed arg or return value: f(int, string) (int, error) { etc }
+ OTYPE, // type name
+ OPACK, // import
+ OLITERAL, // literal
+
+ // expressions
+ OADD, // x + y
+ OSUB, // x - y
+ OOR, // x | y
+ OXOR, // x ^ y
+ OADDSTR, // s + "foo"
+ OADDR, // &x
+ OANDAND, // b0 && b1
+ OAPPEND, // append
+ OARRAYBYTESTR, // string(bytes)
+ OARRAYRUNESTR, // string(runes)
+ OSTRARRAYBYTE, // []byte(s)
+ OSTRARRAYRUNE, // []rune(s)
+ OAS, // x = y or x := y
+ OAS2, // x, y, z = xx, yy, zz
+ OAS2FUNC, // x, y = f()
+ OAS2RECV, // x, ok = <-c
+ OAS2MAPR, // x, ok = m["foo"]
+ OAS2DOTTYPE, // x, ok = I.(int)
+ OASOP, // x += y
+ OCALL, // function call, method call or type conversion, possibly preceded by defer or go.
+ OCALLFUNC, // f()
+ OCALLMETH, // t.Method()
+ OCALLINTER, // err.Error()
+ OCAP, // cap
+ OCLOSE, // close
+ OCLOSURE, // f = func() { etc }
+ OCMPIFACE, // err1 == err2
+ OCMPSTR, // s1 == s2
+ OCOMPLIT, // composite literal, typechecking may convert to a more specific OXXXLIT.
+ OMAPLIT, // M{"foo":3, "bar":4}
+ OSTRUCTLIT, // T{x:3, y:4}
+ OARRAYLIT, // [2]int{3, 4}
+ OPTRLIT, // &T{x:3, y:4}
+ OCONV, // var i int; var u uint; i = int(u)
+ OCONVIFACE, // I(t)
+ OCONVNOP, // type Int int; var i int; var j Int; i = int(j)
+ OCOPY, // copy
+ ODCL, // var x int
+ ODCLFUNC, // func f() or func (r) f()
+ ODCLFIELD, // struct field, interface field, or func/method argument/return value.
+ ODCLCONST, // const pi = 3.14
+ ODCLTYPE, // type Int int
+ ODELETE, // delete
+ ODOT, // t.x
+ ODOTPTR, // p.x that is implicitly (*p).x
+ ODOTMETH, // t.Method
+ ODOTINTER, // err.Error
+ OXDOT, // t.x, typechecking may convert to a more specific ODOTXXX.
+ ODOTTYPE, // e = err.(MyErr)
+ ODOTTYPE2, // e, ok = err.(MyErr)
+ OEQ, // x == y
+ ONE, // x != y
+ OLT, // x < y
+ OLE, // x <= y
+ OGE, // x >= y
+ OGT, // x > y
+ OIND, // *p
+ OINDEX, // a[i]
+ OINDEXMAP, // m[s]
+ OKEY, // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc.
+ OPARAM, // The on-stack copy of a parameter or return value that escapes.
+ OLEN, // len
+ OMAKE, // make, typechecking may convert to a more specfic OMAKEXXX.
+ OMAKECHAN, // make(chan int)
+ OMAKEMAP, // make(map[string]int)
+ OMAKESLICE, // make([]int, 0)
+ OMUL, // x * y
+ ODIV, // x / y
+ OMOD, // x % y
+ OLSH, // x << u
+ ORSH, // x >> u
+ OAND, // x & y
+ OANDNOT, // x &^ y
+ ONEW, // new
+ ONOT, // !b
+ OCOM, // ^x
+ OPLUS, // +x
+ OMINUS, // -y
+ OOROR, // b1 || b2
+ OPANIC, // panic
+ OPRINT, // print
+ OPRINTN, // println
+ OPAREN, // (x)
+ OSEND, // c <- x
+ OSLICE, // v[1:2], typechecking may convert to a more specfic OSLICEXXX.
+ OSLICEARR, // a[1:2]
+ OSLICESTR, // s[1:2]
+ ORECOVER, // recover
+ ORECV, // <-c
+ ORUNESTR, // string(i)
+ OSELRECV, // case x = <-c:
+ OSELRECV2, // case x, ok = <-c:
+ OIOTA, // iota
+ OREAL, // real
+ OIMAG, // imag
+ OCOMPLEX, // complex
+
+ // statements
+ OBLOCK, // block of code
+ OBREAK, // break
+ OCASE, // case, after being verified by swt.c's casebody.
+ OXCASE, // case, before verification.
+ OCONTINUE, // continue
+ ODEFER, // defer
+ OEMPTY, // no-op
+ OFALL, // fallthrough, after being verified by swt.c's casebody.
+ OXFALL, // fallthrough, before verification.
+ OFOR, // for
+ OGOTO, // goto
+ OIF, // if
+ OLABEL, // label:
+ OPROC, // go
+ ORANGE, // range
+ ORETURN, // return
+ OSELECT, // select
+ OSWITCH, // switch x
+ OTYPESW, // switch err.(type)
// types
- OTCHAN,
- OTMAP,
- OTSTRUCT,
- OTINTER,
- OTFUNC,
- OTARRAY,
- OTPAREN,
+ OTCHAN, // chan int
+ OTMAP, // map[string]int
+ OTSTRUCT, // struct{}
+ OTINTER, // interface{}
+ OTFUNC, // func()
+ OTARRAY, // []int, [8]int, [N]int or [...]int
+ OTPAREN, // (T)
// misc
- ODDD,
- ODDDARG,
- OINLCALL, // intermediary representation of an inlined call
- OITAB, // itable word of interface value
-
- // for back ends
- OCMP, ODEC, OEXTEND, OINC, OREGISTER, OINDREG,
+ ODDD, // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
+ ODDDARG, // func f(args ...int), introduced by escape analysis.
+ OINLCALL, // intermediary representation of an inlined call.
+ OEFACE, // itable and data words of an empty-interface value.
+ 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)
+
+ // arch-specific registers
+ OREGISTER, // a register, such as AX.
+ OINDREG, // offset plus indirect of a register, such as 8(SP).
+
+ // 386/amd64-specific opcodes
+ OCMP, // compare: ACMP.
+ ODEC, // decrement: ADEC.
+ OINC, // increment: AINC.
+ OEXTEND, // extend: ACWD/ACDQ/ACQO.
+ OHMUL, // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both).
+ OLROT, // left rotate: AROL.
+ ORROTC, // right rotate-carry: ARCR.
OEND,
};
+
enum
{
Txxx, // 0
@@ -539,6 +624,7 @@ enum
NTYPE,
};
+
enum
{
CTxxx,
@@ -562,18 +648,21 @@ enum
Cboth = Crecv | Csend,
};
+// declaration context
enum
{
Pxxx,
- PEXTERN, // declaration context
- PAUTO,
- PPARAM,
- PPARAMOUT,
- PPARAMREF, // param passed by reference
- PFUNC,
+ PEXTERN, // global variable
+ PAUTO, // local variables
+ PPARAM, // input arguments
+ PPARAMOUT, // output results
+ PPARAMREF, // closure variable reference
+ PFUNC, // global function
- PHEAP = 1<<7,
+ PDISCARD, // discard during parse of duplicate import
+
+ PHEAP = 1<<7, // an extra bit to identify an escaped variable
};
enum
@@ -606,7 +695,6 @@ typedef struct Var Var;
struct Var
{
vlong offset;
- Sym* gotype;
Node* node;
int width;
char name;
@@ -756,7 +844,7 @@ EXTERN int safemode;
EXTERN char namebuf[NSYMB];
EXTERN char lexbuf[NSYMB];
EXTERN char litbuf[NSYMB];
-EXTERN char debug[256];
+EXTERN int debug[256];
EXTERN Sym* hash[NHASH];
EXTERN Sym* importmyname; // my name for package
EXTERN Pkg* localpkg; // package being compiled
@@ -764,11 +852,15 @@ EXTERN Pkg* importpkg; // package being imported
EXTERN Pkg* structpkg; // package that declared struct, during import
EXTERN Pkg* builtinpkg; // fake package for builtins
EXTERN Pkg* gostringpkg; // fake pkg for Go strings
+EXTERN Pkg* itabpkg; // fake pkg for itab cache
EXTERN Pkg* runtimepkg; // package runtime
+EXTERN Pkg* racepkg; // package runtime/race
EXTERN Pkg* stringpkg; // fake package for C strings
-EXTERN Pkg* typepkg; // fake package for runtime type info
+EXTERN Pkg* typepkg; // fake package for runtime type info (headers)
+EXTERN Pkg* typelinkpkg; // fake package for runtime type info (data)
EXTERN Pkg* weaktypepkg; // weak references to runtime type info
EXTERN Pkg* unsafepkg; // package unsafe
+EXTERN Pkg* trackpkg; // fake package for field tracking
EXTERN Pkg* phash[128];
EXTERN int tptr; // either TPTR32 or TPTR64
extern char* runtimeimport;
@@ -815,6 +907,7 @@ EXTERN NodeList* externdcl;
EXTERN NodeList* closures;
EXTERN NodeList* exportlist;
EXTERN NodeList* importlist; // imported functions and methods with inlinable bodies
+EXTERN NodeList* funcsyms;
EXTERN int dclcontext; // PEXTERN/PAUTO
EXTERN int incannedimport;
EXTERN int statuniqgen; // name generator for static temps
@@ -823,8 +916,8 @@ EXTERN int loophack;
EXTERN int32 iota;
EXTERN NodeList* lastconst;
EXTERN Node* lasttype;
-EXTERN int32 maxarg;
-EXTERN int32 stksize; // stack size for current frame
+EXTERN vlong maxarg;
+EXTERN vlong stksize; // stack size for current frame
EXTERN int32 blockgen; // max block number
EXTERN int32 block; // current block number
EXTERN int hasdefer; // flag that curfn has defer statetment
@@ -832,12 +925,14 @@ EXTERN int hasdefer; // flag that curfn has defer statetment
EXTERN Node* curfn;
EXTERN int widthptr;
+EXTERN int widthint;
EXTERN Node* typesw;
EXTERN Node* nblank;
extern int thechar;
extern char* thestring;
+EXTERN int use_sse;
EXTERN char* hunk;
EXTERN int32 nhunk;
@@ -846,6 +941,14 @@ EXTERN int32 thunk;
EXTERN int funcdepth;
EXTERN int typecheckok;
EXTERN int compiling_runtime;
+EXTERN int compiling_wrappers;
+EXTERN int pure_go;
+EXTERN int flag_race;
+EXTERN int flag_largemodel;
+EXTERN int noescape;
+
+EXTERN int nointerface;
+EXTERN int fieldtrack_enabled;
/*
* y.tab.c
@@ -860,7 +963,7 @@ void checkwidth(Type *t);
void defercheckwidth(void);
void dowidth(Type *t);
void resumecheckwidth(void);
-uint32 rnd(uint32 o, uint32 r);
+vlong rnd(vlong o, vlong r);
void typeinit(void);
/*
@@ -898,9 +1001,11 @@ void defaultlit(Node **np, Type *t);
void defaultlit2(Node **lp, Node **rp, int force);
void evconst(Node *n);
int isconst(Node *n, int ct);
+int isgoconst(Node *n);
Node* nodcplxlit(Val r, Val i);
Node* nodlit(Val v);
long nonnegconst(Node *n);
+int doesoverflow(Val v, Type *t);
void overflow(Val v, Type *t);
int smallintconst(Node *n);
Val toint(Val v);
@@ -910,7 +1015,7 @@ Mpflt* truncfltlit(Mpflt *oldv, Type *t);
* cplx.c
*/
void complexadd(int op, Node *nl, Node *nr, Node *res);
-void complexbool(int op, Node *nl, Node *nr, int true, Prog *to);
+void complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to);
void complexgen(Node *n, Node *res);
void complexminus(Node *nl, Node *res);
void complexmove(Node *f, Node *t);
@@ -921,10 +1026,10 @@ void nodfconst(Node *n, Type *t, Mpflt* fval);
/*
* dcl.c
*/
-void addmethod(Sym *sf, Type *t, int local);
+void addmethod(Sym *sf, Type *t, int local, int nointerface);
void addvar(Node *n, Type *t, int ctxt);
NodeList* checkarglist(NodeList *all, int input);
-Node* colas(NodeList *left, NodeList *right);
+Node* colas(NodeList *left, NodeList *right, int32 lno);
void colasdefn(NodeList *left, Node *defn);
NodeList* constiter(NodeList *vl, Node *t, NodeList *cl);
Node* dclname(Sym *s);
@@ -954,6 +1059,7 @@ Node* typedcl0(Sym *s);
Node* typedcl1(Node *n, Node *t, int local);
Node* typenod(Type *t);
NodeList* variter(NodeList *vl, Node *t, NodeList *el);
+Sym* funcsym(Sym*);
/*
* esc.c
@@ -987,6 +1093,8 @@ void dumplist(char *s, NodeList *l);
void addrescapes(Node *n);
void cgen_as(Node *nl, Node *nr);
void cgen_callmeth(Node *n, int proc);
+void cgen_eface(Node* n, Node* res);
+void cgen_slice(Node* n, Node* res);
void clearlabels(void);
void checklabels(void);
int dotoffset(Node *n, int *oary, Node **nn);
@@ -1115,8 +1223,11 @@ void dumptypestructs(void);
Type* methodfunc(Type *f, Type*);
Node* typename(Type *t);
Sym* typesym(Type *t);
+Sym* typenamesym(Type *t);
+Sym* tracksym(Type *t);
Sym* typesymprefix(char *prefix, Type *t);
int haspointers(Type *t);
+void usefield(Node*);
/*
* select.c
@@ -1214,6 +1325,7 @@ Node* safeexpr(Node *n, NodeList **init);
void saveerrors(void);
Node* cheapexpr(Node *n, NodeList **init);
Node* localexpr(Node *n, Type *t, NodeList **init);
+void saveorignode(Node *n);
int32 setlineno(Node *n);
void setmaxarg(Type *t);
Type* shallow(Type *t);
@@ -1274,6 +1386,7 @@ void walkexprlistsafe(NodeList *l, NodeList **init);
void walkstmt(Node **np);
void walkstmtlist(NodeList *l);
Node* conv(Node*, Type*);
+int candiscard(Node*);
/*
* arch-specific ggen.c/gsubr.c/gobj.c/pgen.c
@@ -1302,7 +1415,8 @@ EXTERN Node* nodfp;
int anyregalloc(void);
void betypeinit(void);
-void bgen(Node *n, int true, Prog *to);
+void bgen(Node *n, int true, int likely, Prog *to);
+void checkref(Node*);
void cgen(Node*, Node*);
void cgen_asop(Node *n);
void cgen_call(Node *n, int proc);
@@ -1323,8 +1437,8 @@ void gdata(Node*, Node*, int);
void gdatacomplex(Node*, Mpcplx*);
void gdatastring(Node*, Strlit*);
void genembedtramp(Type*, Type*, Sym*, int iface);
-void ggloblnod(Node *nam, int32 width);
-void ggloblsym(Sym *s, int32 width, int dupok);
+void ggloblnod(Node *nam);
+void ggloblsym(Sym *s, int32 width, int dupok, int rodata);
Prog* gjmp(Prog*);
void gused(Node*);
int isfat(Type*);
@@ -1364,3 +1478,8 @@ void zname(Biobuf *b, Sym *s, int t);
#pragma varargck type "V" Val*
#pragma varargck type "Y" char*
#pragma varargck type "Z" Strlit*
+
+/*
+ * racewalk.c
+ */
+void racewalk(Node *fn);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index f95058721..794961e8e 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -37,8 +37,8 @@ static void fixlbrace(int);
// |sed 's/.* //' |9 fmt -l1 |sort |9 fmt -l50 | sed 's/^/%xxx /'
%token <val> LLITERAL
-%token <i> LASOP
-%token <sym> LBREAK LCASE LCHAN LCOLAS LCONST LCONTINUE LDDD
+%token <i> LASOP LCOLAS
+%token <sym> LBREAK LCASE LCHAN LCONST LCONTINUE LDDD
%token <sym> LDEFAULT LDEFER LELSE LFALL LFOR LFUNC LGO LGOTO
%token <sym> LIF LIMPORT LINTERFACE LMAP LNAME
%token <sym> LPACKAGE LRANGE LRETURN LSELECT LSTRUCT LSWITCH
@@ -54,10 +54,10 @@ static void fixlbrace(int);
%type <node> stmt ntype
%type <node> arg_type
%type <node> case caseblock
-%type <node> compound_stmt dotname embed expr complitexpr
+%type <node> compound_stmt dotname embed expr complitexpr bare_complitexpr
%type <node> expr_or_type
%type <node> fndcl hidden_fndcl fnliteral
-%type <node> for_body for_header for_stmt if_header if_stmt else non_dcl_stmt
+%type <node> for_body for_header for_stmt if_header if_stmt non_dcl_stmt
%type <node> interfacedcl keyval labelname name
%type <node> name_or_type non_expr_type
%type <node> new_name dcl_name oexpr typedclname
@@ -70,7 +70,7 @@ static void fixlbrace(int);
%type <list> xdcl fnbody fnres loop_body dcl_name_list
%type <list> new_name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list
-%type <list> oexpr_list caseblock_list stmt_list oarg_type_list_ocomma arg_type_list
+%type <list> oexpr_list caseblock_list elseif elseif_list else stmt_list oarg_type_list_ocomma arg_type_list
%type <list> interfacedcl_list vardcl vardcl_list structdcl structdcl_list
%type <list> common_dcl constdcl constdcl1 constdcl_list typedcl_list
@@ -405,6 +405,20 @@ simple_stmt:
expr
{
$$ = $1;
+
+ // These nodes do not carry line numbers.
+ // Since a bare name used as an expression is an error,
+ // introduce a wrapper node to give the correct line.
+ switch($$->op) {
+ case ONAME:
+ case ONONAME:
+ case OTYPE:
+ case OPACK:
+ case OLITERAL:
+ $$ = nod(OPAREN, $$, N);
+ $$->implicit = 1;
+ break;
+ }
}
| expr LASOP expr
{
@@ -437,7 +451,7 @@ simple_stmt:
$$->left = dclname($1->n->sym); // it's a colas, so must not re-use an oldname.
break;
}
- $$ = colas($1, $3);
+ $$ = colas($1, $3, $2);
}
| expr LINC
{
@@ -496,7 +510,7 @@ case:
// done in casebody()
markdcl();
$$ = nod(OXCASE, N, N);
- $$->list = list1(colas($2, list1($4)));
+ $$->list = list1(colas($2, list1($4), $3));
}
| LDEFAULT ':'
{
@@ -661,25 +675,56 @@ if_stmt:
{
$3->nbody = $5;
}
- else
+ elseif_list else
{
- popdcl();
+ Node *n;
+ NodeList *nn;
+
$$ = $3;
- if($7 != N)
- $$->nelse = list1($7);
+ n = $3;
+ popdcl();
+ for(nn = concat($7, $8); nn; nn = nn->next) {
+ if(nn->n->op == OIF)
+ popdcl();
+ n->nelse = list1(nn->n);
+ n = nn->n;
+ }
}
-else:
+elseif:
+ LELSE LIF
{
- $$ = N;
+ markdcl();
}
-| LELSE if_stmt
+ if_header loop_body
{
- $$ = $2;
+ if($4->ntest == N)
+ yyerror("missing condition in if statement");
+ $4->nbody = $5;
+ $$ = list1($4);
+ }
+
+elseif_list:
+ {
+ $$ = nil;
+ }
+| elseif_list elseif
+ {
+ $$ = concat($1, $2);
+ }
+
+else:
+ {
+ $$ = nil;
}
| LELSE compound_stmt
{
- $$ = $2;
+ NodeList *node;
+
+ node = mal(sizeof *node);
+ node->n = $2;
+ node->end = node;
+ $$ = node;
}
switch_stmt:
@@ -902,7 +947,7 @@ pexpr_no_paren:
$$ = nod(OSLICE, $1, nod(OKEY, $3, $5));
}
| pseudocall
-| convtype '(' expr ')'
+| convtype '(' expr ocomma ')'
{
// conversion
$$ = nod(OCALL, $1, N);
@@ -943,6 +988,30 @@ keyval:
$$ = nod(OKEY, $1, $3);
}
+bare_complitexpr:
+ expr
+ {
+ // These nodes do not carry line numbers.
+ // Since a composite literal commonly spans several lines,
+ // the line number on errors may be misleading.
+ // Introduce a wrapper node to give the correct line.
+ $$ = $1;
+ switch($$->op) {
+ case ONAME:
+ case ONONAME:
+ case OTYPE:
+ case OPACK:
+ case OLITERAL:
+ $$ = nod(OPAREN, $$, N);
+ $$->implicit = 1;
+ }
+ }
+| '{' start_complit braced_keyval_list '}'
+ {
+ $$ = $2;
+ $$->list = $3;
+ }
+
complitexpr:
expr
| '{' start_complit braced_keyval_list '}'
@@ -966,6 +1035,7 @@ pexpr:
case OPACK:
case OTYPE:
case OLITERAL:
+ case OTYPESW:
$$ = nod(OPAREN, $$, N);
}
}
@@ -1030,10 +1100,16 @@ sym:
hidden_importsym:
'@' LLITERAL '.' LNAME
{
+ Pkg *p;
+
if($2.u.sval->len == 0)
- $$ = pkglookup($4->name, importpkg);
- else
- $$ = pkglookup($4->name, mkpkg($2.u.sval));
+ p = importpkg;
+ else {
+ if(isbadimport($2.u.sval))
+ errorexit();
+ p = mkpkg($2.u.sval);
+ }
+ $$ = pkglookup($4->name, p);
}
name:
@@ -1201,8 +1277,11 @@ xfndcl:
$$ = $2;
if($$ == N)
break;
+ if(noescape && $3 != nil)
+ yyerror("can only use //go:noescape with external func implementations");
$$->nbody = $3;
$$->endlineno = lineno;
+ $$->noescape = noescape;
funcbody($$);
}
@@ -1269,6 +1348,7 @@ fndcl:
$$->nname = methodname1($$->shortname, rcvr->right);
$$->nname->defn = $$;
$$->nname->ntype = t;
+ $$->nname->nointerface = nointerface;
declare($$->nname, PFUNC);
funchdr($$);
@@ -1287,8 +1367,10 @@ hidden_fndcl:
importsym(s, ONAME);
if(s->def != N && s->def->op == ONAME) {
- if(eqtype(t, s->def->type))
+ if(eqtype(t, s->def->type)) {
+ dclcontext = PDISCARD; // since we skip funchdr below
break;
+ }
yyerror("inconsistent definition for func %S during import\n\t%T\n\t%T", s, s->def->type, t);
}
@@ -1304,7 +1386,8 @@ hidden_fndcl:
$$->type = functype($2->n, $6, $8);
checkwidth($$->type);
- addmethod($4, $$->type, 0);
+ addmethod($4, $$->type, 0, nointerface);
+ nointerface = 0;
funchdr($$);
// inl.c's inlnode in on a dotmeth node expects to find the inlineable body as
@@ -1381,6 +1464,8 @@ xdcl_list:
$$ = concat($1, $2);
if(nsyntaxerrors == 0)
testdclstack();
+ nointerface = 0;
+ noescape = 0;
}
vardcl_list:
@@ -1719,7 +1804,7 @@ keyval_list:
{
$$ = list1($1);
}
-| complitexpr
+| bare_complitexpr
{
$$ = list1($1);
}
@@ -1727,7 +1812,7 @@ keyval_list:
{
$$ = list($1, $3);
}
-| keyval_list ',' complitexpr
+| keyval_list ',' bare_complitexpr
{
$$ = list($1, $3);
}
@@ -1818,8 +1903,10 @@ hidden_import:
}
| LFUNC hidden_fndcl fnbody ';'
{
- if($2 == N)
+ if($2 == N) {
+ dclcontext = PEXTERN; // since we skip the funcbody below
break;
+ }
$2->inl = $3;
@@ -1828,7 +1915,7 @@ hidden_import:
if(debug['E']) {
print("import [%Z] func %lN \n", importpkg->path, $2);
- if(debug['l'] > 2 && $2->inl)
+ if(debug['m'] > 2 && $2->inl)
print("inl body:%+H\n", $2->inl);
}
}
@@ -2039,6 +2126,8 @@ hidden_constant:
mpaddfixfix($2->val.u.xval, $4->val.u.xval, 0);
break;
}
+ $4->val.u.cval->real = $4->val.u.cval->imag;
+ mpmovecflt(&$4->val.u.cval->imag, 0.0);
$$ = nodcplxlit($2->val, $4->val);
}
diff --git a/src/cmd/gc/init.c b/src/cmd/gc/init.c
index be402cc0c..918d37180 100644
--- a/src/cmd/gc/init.c
+++ b/src/cmd/gc/init.c
@@ -55,6 +55,10 @@ anyinit(NodeList *n)
case ODCLTYPE:
case OEMPTY:
break;
+ case OAS:
+ if(isblank(l->n->left) && candiscard(l->n->right))
+ break;
+ // fall through
default:
return 1;
}
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c
index b2b1faff7..1cc13a304 100644
--- a/src/cmd/gc/inl.c
+++ b/src/cmd/gc/inl.c
@@ -13,7 +13,7 @@
// 0: disabled
// 1: 40-nodes leaf functions, oneliners, lazy typechecking (default)
// 2: early typechecking of all imported bodies
-// 3:
+// 3: allow variadic functions
// 4: allow non-leaf functions , (breaks runtime.Caller)
// 5: transitive inlining
//
@@ -39,9 +39,10 @@ static int ishairylist(NodeList *ll, int *budget);
// Used by inlcalls
static void inlnodelist(NodeList *l);
static void inlnode(Node **np);
-static void mkinlcall(Node **np, Node *fn);
+static void mkinlcall(Node **np, Node *fn, int isddd);
static Node* inlvar(Node *n);
static Node* retvar(Type *n, int i);
+static Node* argvar(Type *n, int i);
static Node* newlabel(void);
static Node* inlsubst(Node *n);
static NodeList* inlsubstlist(NodeList *l);
@@ -82,20 +83,18 @@ typecheckinl(Node *fn)
Pkg *pkg;
int save_safemode, lno;
- if(fn->typecheck)
- return;
-
lno = setlineno(fn);
- if (debug['m']>2)
- print("typecheck import [%S] %lN { %#H }\n", fn->sym, fn, fn->inl);
-
- // typecheckinl is only used for imported functions;
+ // typecheckinl is only for imported functions;
// their bodies may refer to unsafe as long as the package
// was marked safe during import (which was checked then).
+ // the ->inl of a local function has been typechecked before caninl copied it.
pkg = fnpkg(fn);
if (pkg == localpkg || pkg == nil)
- fatal("typecheckinl on local function %lN", fn);
+ return; // typecheckinl on local function
+
+ if (debug['m']>2)
+ print("typecheck import [%S] %lN { %#H }\n", fn->sym, fn, fn->inl);
save_safemode = safemode;
safemode = 0;
@@ -103,7 +102,6 @@ typecheckinl(Node *fn)
savefn = curfn;
curfn = fn;
typechecklist(fn->inl, Etop);
- fn->typecheck = 1;
curfn = savefn;
safemode = save_safemode;
@@ -111,10 +109,9 @@ typecheckinl(Node *fn)
lineno = lno;
}
-// Caninl determines whether fn is inlineable. Currently that means:
-// fn is exactly 1 statement, either a return or an assignment, and
-// some temporary constraints marked TODO. If fn is inlineable, saves
-// fn->nbody in fn->inl and substitutes it with a copy.
+// Caninl determines whether fn is inlineable.
+// If so, caninl saves fn->nbody in fn->inl and substitutes it with a copy.
+// fn and ->nbody will already have been typechecked.
void
caninl(Node *fn)
{
@@ -131,10 +128,14 @@ caninl(Node *fn)
if(fn->nbody == nil)
return;
+ if(fn->typecheck == 0)
+ fatal("caninl on non-typechecked function %N", fn);
+
// can't handle ... args yet
- for(t=fn->type->type->down->down->type; t; t=t->down)
- if(t->isddd)
- return;
+ if(debug['l'] < 3)
+ for(t=fn->type->type->down->down->type; t; t=t->down)
+ if(t->isddd)
+ return;
budget = 40; // allowed hairyness
if(ishairylist(fn->nbody, &budget))
@@ -145,8 +146,6 @@ caninl(Node *fn)
fn->nname->inl = fn->nbody;
fn->nbody = inlcopylist(fn->nname->inl);
- // nbody will have been typechecked, so we can set this:
- fn->typecheck = 1;
// hack, TODO, check for better way to link method nodes back to the thing with the ->inl
// this is so export can find the body of a method
@@ -195,19 +194,11 @@ ishairy(Node *n, int *budget)
case OSWITCH:
case OPROC:
case ODEFER:
- case ODCL: // declares locals as globals b/c of @"". qualification
case ODCLTYPE: // can't print yet
case ODCLCONST: // can't print yet
return 1;
break;
- case OAS:
- // x = <N> zero initializing assignments aren't representible in export yet.
- // alternatively we may just skip them in printing and hope their DCL printed
- // as a var will regenerate it
- if(n->right == N)
- return 1;
- break;
}
(*budget)--;
@@ -366,8 +357,8 @@ inlnode(Node **np)
}
case OCLOSURE:
- // TODO do them here instead of in lex.c phase 6b, so escape analysis
- // can avoid more heapmoves.
+ // TODO do them here (or earlier) instead of in walkcallclosure,
+ // so escape analysis can avoid more heapmoves.
return;
}
@@ -464,10 +455,10 @@ inlnode(Node **np)
if(debug['m']>3)
print("%L:call to func %+N\n", n->lineno, n->left);
if(n->left->inl) // normal case
- mkinlcall(np, n->left);
+ mkinlcall(np, n->left, n->isddd);
else if(n->left->op == ONAME && n->left->left && n->left->left->op == OTYPE && n->left->right && n->left->right->op == ONAME) // methods called as functions
if(n->left->sym->def)
- mkinlcall(np, n->left->sym->def);
+ mkinlcall(np, n->left->sym->def, n->isddd);
break;
case OCALLMETH:
@@ -480,7 +471,7 @@ inlnode(Node **np)
if(n->left->type->nname == N)
fatal("no function definition for [%p] %+T\n", n->left->type, n->left->type);
- mkinlcall(np, n->left->type->nname);
+ mkinlcall(np, n->left->type->nname, n->isddd);
break;
}
@@ -488,10 +479,10 @@ inlnode(Node **np)
lineno = lno;
}
-static void mkinlcall1(Node **np, Node *fn);
+static void mkinlcall1(Node **np, Node *fn, int isddd);
static void
-mkinlcall(Node **np, Node *fn)
+mkinlcall(Node **np, Node *fn, int isddd)
{
int save_safemode;
Pkg *pkg;
@@ -503,7 +494,7 @@ mkinlcall(Node **np, Node *fn)
pkg = fnpkg(fn);
if(pkg != localpkg && pkg != nil)
safemode = 0;
- mkinlcall1(np, fn);
+ mkinlcall1(np, fn, isddd);
safemode = save_safemode;
}
@@ -519,17 +510,25 @@ tinlvar(Type *t)
return nblank;
}
+static int inlgen;
+
// if *np is a call, and fn is a function with an inlinable body, substitute *np with an OINLCALL.
// On return ninit has the parameter assignments, the nbody is the
// inlined function body and list, rlist contain the input, output
// parameters.
static void
-mkinlcall1(Node **np, Node *fn)
+mkinlcall1(Node **np, Node *fn, int isddd)
{
int i;
+ int chkargcount;
Node *n, *call, *saveinlfn, *as, *m;
NodeList *dcl, *ll, *ninit, *body;
Type *t;
+ // For variadic fn.
+ int variadic, varargcount, multiret;
+ Node *vararg;
+ NodeList *varargs;
+ Type *varargtype, *vararrtype;
if (fn->inl == nil)
return;
@@ -556,6 +555,8 @@ mkinlcall1(Node **np, Node *fn)
ninit = n->ninit;
+//dumplist("ninit pre", ninit);
+
if (fn->defn) // local function
dcl = fn->defn->dcl;
else // imported function
@@ -567,7 +568,10 @@ mkinlcall1(Node **np, Node *fn)
for(ll = dcl; ll; ll=ll->next)
if(ll->n->op == ONAME) {
ll->n->inlvar = inlvar(ll->n);
- ninit = list(ninit, nod(ODCL, ll->n->inlvar, N)); // otherwise gen won't emit the allocations for heapallocs
+ // 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);
}
@@ -580,49 +584,118 @@ mkinlcall1(Node **np, Node *fn)
inlretvars = list(inlretvars, m);
}
- // assign arguments to the parameters' temp names
- as = N;
- if(fn->type->thistuple) {
+ // assign receiver.
+ if(fn->type->thistuple && n->left->op == ODOTMETH) {
+ // method call with a receiver.
t = getthisx(fn->type)->type;
if(t != T && t->nname != N && !isblank(t->nname) && !t->nname->inlvar)
fatal("missing inlvar for %N\n", t->nname);
-
- if(n->left->op == ODOTMETH) {
- if(!n->left->left)
- fatal("method call without receiver: %+N", n);
- if(t == T)
- fatal("method call unknown receiver type: %+N", n);
- as = nod(OAS, tinlvar(t), n->left->left);
- } else { // non-method call to method
- if(!n->list)
- fatal("non-method call to method without first arg: %+N", n);
- if(t != T)
- as = nod(OAS, tinlvar(t), n->list->n);
- }
-
+ if(!n->left->left)
+ fatal("method call without receiver: %+N", n);
+ if(t == T)
+ fatal("method call unknown receiver type: %+N", n);
+ as = nod(OAS, tinlvar(t), n->left->left);
if(as != N) {
typecheck(&as, Etop);
ninit = list(ninit, as);
}
}
+ // check if inlined function is variadic.
+ variadic = 0;
+ varargtype = T;
+ varargcount = 0;
+ for(t=fn->type->type->down->down->type; t; t=t->down) {
+ if(t->isddd) {
+ variadic = 1;
+ varargtype = t->type;
+ }
+ }
+ // but if argument is dotted too forget about variadicity.
+ if(variadic && isddd)
+ variadic = 0;
+
+ // check if argument is actually a returned tuple from call.
+ multiret = 0;
+ if(n->list && !n->list->next) {
+ switch(n->list->n->op) {
+ case OCALL:
+ case OCALLFUNC:
+ case OCALLINTER:
+ case OCALLMETH:
+ if(n->list->n->left->type->outtuple > 1)
+ multiret = n->list->n->left->type->outtuple-1;
+ }
+ }
+
+ if(variadic) {
+ varargcount = count(n->list) + multiret;
+ if(n->left->op != ODOTMETH)
+ varargcount -= fn->type->thistuple;
+ varargcount -= fn->type->intuple - 1;
+ }
+
+ // assign arguments to the parameters' temp names
as = nod(OAS2, N, N);
- if(fn->type->intuple > 1 && n->list && !n->list->next) {
- // TODO check that n->list->n is a call?
- // TODO: non-method call to T.meth(f()) where f returns t, args...
- as->rlist = n->list;
- for(t = getinargx(fn->type)->type; t; t=t->down)
- as->list = list(as->list, tinlvar(t));
- } else {
- ll = n->list;
- if(fn->type->thistuple && n->left->op != ODOTMETH) // non method call to method
- ll=ll->next; // was handled above in if(thistuple)
+ as->rlist = n->list;
+ ll = n->list;
+
+ // TODO: if len(nlist) == 1 but multiple args, check that n->list->n is a call?
+ if(fn->type->thistuple && n->left->op != ODOTMETH) {
+ // non-method call to method
+ if(!n->list)
+ fatal("non-method call to method without first arg: %+N", n);
+ // append receiver inlvar to LHS.
+ t = getthisx(fn->type)->type;
+ if(t != T && t->nname != N && !isblank(t->nname) && !t->nname->inlvar)
+ fatal("missing inlvar for %N\n", t->nname);
+ if(t == T)
+ fatal("method call unknown receiver type: %+N", n);
+ as->list = list(as->list, tinlvar(t));
+ ll = ll->next; // track argument count.
+ }
- for(t = getinargx(fn->type)->type; t && ll; t=t->down) {
+ // append ordinary arguments to LHS.
+ chkargcount = n->list && n->list->next;
+ vararg = N; // the slice argument to a variadic call
+ varargs = nil; // the list of LHS names to put in vararg.
+ if(!chkargcount) {
+ // 0 or 1 expression on RHS.
+ for(t = getinargx(fn->type)->type; t; t=t->down) {
+ if(variadic && t->isddd) {
+ vararg = tinlvar(t);
+ for(i=0; i<varargcount && ll; i++) {
+ m = argvar(varargtype, i);
+ varargs = list(varargs, m);
+ as->list = list(as->list, m);
+ }
+ break;
+ }
+ as->list = list(as->list, tinlvar(t));
+ }
+ } else {
+ // match arguments except final variadic (unless the call is dotted itself)
+ for(t = getinargx(fn->type)->type; t;) {
+ if(!ll)
+ break;
+ if(variadic && t->isddd)
+ break;
as->list = list(as->list, tinlvar(t));
- as->rlist = list(as->rlist, ll->n);
+ t=t->down;
ll=ll->next;
}
+ // match varargcount arguments with variadic parameters.
+ if(variadic && t && t->isddd) {
+ vararg = tinlvar(t);
+ for(i=0; i<varargcount && ll; i++) {
+ m = argvar(varargtype, i);
+ varargs = list(varargs, m);
+ as->list = list(as->list, m);
+ ll=ll->next;
+ }
+ if(i==varargcount)
+ t=t->down;
+ }
if(ll || t)
fatal("arg count mismatch: %#T vs %,H\n", getinargx(fn->type), n->list);
}
@@ -632,6 +705,25 @@ mkinlcall1(Node **np, Node *fn)
ninit = list(ninit, as);
}
+ // turn the variadic args into a slice.
+ if(variadic) {
+ as = nod(OAS, vararg, N);
+ if(!varargcount) {
+ as->right = nodnil();
+ as->right->type = varargtype;
+ } else {
+ vararrtype = typ(TARRAY);
+ vararrtype->type = varargtype->type;
+ vararrtype->bound = varargcount;
+
+ as->right = nod(OCOMPLIT, N, typenod(varargtype));
+ as->right->list = varargs;
+ as->right = nod(OSLICE, as->right, nod(OKEY, N, N));
+ }
+ typecheck(&as, Etop);
+ ninit = list(ninit, as);
+ }
+
// zero the outparams
for(ll = inlretvars; ll; ll=ll->next) {
as = nod(OAS, ll->n, N);
@@ -640,12 +732,14 @@ mkinlcall1(Node **np, Node *fn)
}
inlretlabel = newlabel();
+ inlgen++;
body = inlsubstlist(fn->inl);
body = list(body, nod(OGOTO, inlretlabel, N)); // avoid 'not used' when function doesnt have return
body = list(body, nod(OLABEL, inlretlabel, N));
typechecklist(body, Etop);
+//dumplist("ninit post", ninit);
call = nod(OINLCALL, N, N);
call->ninit = ninit;
@@ -655,6 +749,7 @@ mkinlcall1(Node **np, Node *fn)
call->typecheck = 1;
setlno(call, n->lineno);
+//dumplist("call body", body);
*np = call;
@@ -705,7 +800,24 @@ retvar(Type *t, int i)
{
Node *n;
- snprint(namebuf, sizeof(namebuf), ".r%d", i);
+ snprint(namebuf, sizeof(namebuf), "~r%d", i);
+ n = newname(lookup(namebuf));
+ n->type = t->type;
+ n->class = PAUTO;
+ n->used = 1;
+ n->curfn = curfn; // the calling function, not the called one
+ curfn->dcl = list(curfn->dcl, n);
+ return n;
+}
+
+// Synthesize a variable to store the inlined function's arguments
+// when they come from a multiple return call.
+static Node*
+argvar(Type *t, int i)
+{
+ Node *n;
+
+ snprint(namebuf, sizeof(namebuf), "~arg%d", i);
n = newname(lookup(namebuf));
n->type = t->type;
n->class = PAUTO;
@@ -746,6 +858,7 @@ inlsubstlist(NodeList *ll)
static Node*
inlsubst(Node *n)
{
+ char *p;
Node *m, *as;
NodeList *ll;
@@ -788,6 +901,16 @@ inlsubst(Node *n)
typecheck(&m, Etop);
// dump("Return after substitution", m);
return m;
+
+ case OGOTO:
+ case OLABEL:
+ m = nod(OXXX, N, N);
+ *m = *n;
+ m->ninit = nil;
+ p = smprint("%s·%d", n->left->sym->name, inlgen);
+ m->left = newname(lookup(p));
+ free(p);
+ return m;
}
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 624dfb0b4..68ae6864d 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -30,6 +30,8 @@ static void addidir(char*);
static int getlinepragma(void);
static char *goos, *goarch, *goroot;
+#define BOM 0xFEFF
+
// Compiler experiments.
// These are controlled by the GOEXPERIMENT environment
// variable recorded when the compiler is built.
@@ -38,6 +40,7 @@ static struct {
int *val;
} exper[] = {
// {"rune32", &rune32},
+ {"fieldtrack", &fieldtrack_enabled},
{nil, nil},
};
@@ -96,7 +99,7 @@ yy_isdigit(int c)
static int
yy_isspace(int c)
{
- return c >= 0 && c <= 0xFF && isspace(c);
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r';
}
static int
@@ -130,42 +133,8 @@ enum
void
usage(void)
{
- print("gc: usage: %cg [flags] file.go...\n", thechar);
- print("flags:\n");
- // -A allow use of "any" type, for bootstrapping
- // -B disable bounds checking
- // -E print imported declarations
- // -K warn when lineno is zero
- // -M print arguments to gmove
- // -P print peephole diagnostics
- // -R print optimizer diagnostics
- // -g print code generation diagnostics
- // -i print line history
- // -j print variables to be initialized at runtime
- // -r print generated helper functions
- // -s print redundant types in composite literals
- // -v print more information with -P or -R
- // -y print declarations in cannedimports (used with -d)
- // -% print non-static initializers
- // -+ indicate that the runtime is being compiled
- print(" -D PATH interpret local imports relative to this import path\n");
- print(" -I DIR search for packages in DIR\n");
- print(" -L show full path in file:line prints\n");
- print(" -N disable optimizations\n");
- print(" -S print the assembly language\n");
- print(" -V print the compiler version\n");
- print(" -W print the parse tree after typing\n");
- print(" -d print declarations\n");
- print(" -e no limit on number of errors printed\n");
- print(" -f print stack frame structure\n");
- print(" -h panic on an error\n");
- print(" -l disable inlining\n");
- print(" -m print optimization decisions\n");
- print(" -o file specify output file\n");
- print(" -p assumed import path for this code\n");
- print(" -u disable package unsafe\n");
- print(" -w print type checking details\n");
- print(" -x print lex tokens\n");
+ print("usage: %cg [options] file.go...\n", thechar);
+ flagprint(1);
exits("usage");
}
@@ -183,11 +152,23 @@ fault(int s)
fatal("fault");
}
+void
+doversion(void)
+{
+ char *p;
+
+ p = expstring();
+ if(strcmp(p, "X:none") == 0)
+ p = "";
+ print("%cg version %s%s%s\n", thechar, getgoversion(), *p ? " " : "", p);
+ exits(0);
+}
+
int
main(int argc, char *argv[])
{
- int i, c;
- NodeList *l, *batch;
+ int i;
+ NodeList *l;
char *p;
#ifdef SIGBUS
@@ -197,25 +178,41 @@ main(int argc, char *argv[])
localpkg = mkpkg(strlit(""));
localpkg->prefix = "\"\"";
-
+
+ // pseudo-package, for scoping
builtinpkg = mkpkg(strlit("go.builtin"));
+ // pseudo-package, accessed by import "unsafe"
+ unsafepkg = mkpkg(strlit("unsafe"));
+ unsafepkg->name = "unsafe";
+
+ // real package, referred to by generated runtime calls
+ runtimepkg = mkpkg(strlit("runtime"));
+ runtimepkg->name = "runtime";
+
+ // pseudo-packages used in symbol tables
gostringpkg = mkpkg(strlit("go.string"));
gostringpkg->name = "go.string";
gostringpkg->prefix = "go.string"; // not go%2estring
- runtimepkg = mkpkg(strlit("runtime"));
- runtimepkg->name = "runtime";
+ itabpkg = mkpkg(strlit("go.itab"));
+ itabpkg->name = "go.itab";
+ itabpkg->prefix = "go.itab"; // not go%2eitab
- typepkg = mkpkg(strlit("type"));
- typepkg->name = "type";
+ weaktypepkg = mkpkg(strlit("go.weak.type"));
+ weaktypepkg->name = "go.weak.type";
+ weaktypepkg->prefix = "go.weak.type"; // not go%2eweak%2etype
+
+ typelinkpkg = mkpkg(strlit("go.typelink"));
+ typelinkpkg->name = "go.typelink";
+ typelinkpkg->prefix = "go.typelink"; // not go%2etypelink
- weaktypepkg = mkpkg(strlit("weak.type"));
- weaktypepkg->name = "weak.type";
- weaktypepkg->prefix = "weak.type"; // not weak%2etype
+ trackpkg = mkpkg(strlit("go.track"));
+ trackpkg->name = "go.track";
+ trackpkg->prefix = "go.track"; // not go%2etrack
- unsafepkg = mkpkg(strlit("unsafe"));
- unsafepkg->name = "unsafe";
+ typepkg = mkpkg(strlit("type"));
+ typepkg->name = "type";
goroot = getgoroot();
goos = getgoos();
@@ -224,41 +221,55 @@ main(int argc, char *argv[])
setexp();
outfile = nil;
- ARGBEGIN {
- default:
- c = ARGC();
- if(c >= 0 && c < sizeof(debug))
- debug[c]++;
- break;
-
- case 'o':
- outfile = EARGF(usage());
- break;
-
- case 'p':
- myimportpath = EARGF(usage());
- break;
+ flagcount("+", "compiling runtime", &compiling_runtime);
+ flagcount("%", "debug non-static initializers", &debug['%']);
+ flagcount("A", "for bootstrapping, allow 'any' type", &debug['A']);
+ flagcount("B", "disable bounds checking", &debug['B']);
+ flagstr("D", "path: set relative path for local imports", &localimport);
+ flagcount("E", "debug symbol export", &debug['E']);
+ flagfn1("I", "dir: add dir to import search path", addidir);
+ flagcount("K", "debug missing line numbers", &debug['K']);
+ flagcount("L", "use full (long) path in error messages", &debug['L']);
+ flagcount("M", "debug move generation", &debug['M']);
+ flagcount("N", "disable optimizations", &debug['N']);
+ flagcount("P", "debug peephole optimizer", &debug['P']);
+ flagcount("R", "debug register optimizer", &debug['R']);
+ flagcount("S", "print assembly listing", &debug['S']);
+ flagfn0("V", "print compiler version", doversion);
+ flagcount("W", "debug parse tree after type checking", &debug['W']);
+ flagcount("complete", "compiling complete package (no C or assembly)", &pure_go);
+ flagcount("d", "debug declarations", &debug['d']);
+ flagcount("e", "no limit on number of errors reported", &debug['e']);
+ flagcount("f", "debug stack frames", &debug['f']);
+ flagcount("g", "debug code generation", &debug['g']);
+ flagcount("h", "halt on error", &debug['h']);
+ flagcount("i", "debug line number stack", &debug['i']);
+ flagcount("j", "debug runtime-initialized variables", &debug['j']);
+ flagcount("l", "disable inlining", &debug['l']);
+ flagcount("m", "print optimization decisions", &debug['m']);
+ flagstr("o", "obj: set output file", &outfile);
+ flagstr("p", "path: set expected package import path", &myimportpath);
+ flagcount("r", "debug generated wrappers", &debug['r']);
+ flagcount("race", "enable race detector", &flag_race);
+ flagcount("s", "warn about composite literals that can be simplified", &debug['s']);
+ flagcount("u", "reject unsafe code", &safemode);
+ flagcount("v", "increase debug verbosity", &debug['v']);
+ flagcount("w", "debug type checking", &debug['w']);
+ flagcount("x", "debug lexer", &debug['x']);
+ flagcount("y", "debug declarations in canned imports (with -d)", &debug['y']);
+ if(thechar == '6')
+ flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
+
+ flagparse(&argc, &argv, usage);
- case 'u':
- safemode = 1;
- break;
+ if(argc < 1)
+ usage();
- case 'D':
- localimport = EARGF(usage());
- break;
+ if(flag_race) {
+ racepkg = mkpkg(strlit("runtime/race"));
+ racepkg->name = "race";
+ }
- case 'I':
- addidir(EARGF(usage()));
- break;
-
- case 'V':
- p = expstring();
- if(strcmp(p, "X:none") == 0)
- p = "";
- print("%cg version %s%s%s\n", thechar, getgoversion(), *p ? " " : "", p);
- exits(0);
- } ARGEND
-
// enable inlining. for now:
// default: inlining on. (debug['l'] == 1)
// -l: inlining off (debug['l'] == 0)
@@ -266,11 +277,15 @@ main(int argc, char *argv[])
if(debug['l'] <= 1)
debug['l'] = 1 - debug['l'];
- if(argc < 1)
- usage();
-
- // special flag to detect compilation of package runtime
- compiling_runtime = debug['+'];
+ if(thechar == '8') {
+ p = getgo386();
+ if(strcmp(p, "387") == 0)
+ use_sse = 0;
+ else if(strcmp(p, "sse2") == 0)
+ use_sse = 1;
+ else
+ sysfatal("unsupported setting GO386=%s", p);
+ }
pathname = mal(1000);
if(getwd(pathname, 999) == 0)
@@ -315,6 +330,10 @@ main(int argc, char *argv[])
curio.peekc1 = 0;
curio.nlsemi = 0;
+ // Skip initial BOM if present.
+ if(Bgetrune(curio.bin) != BOM)
+ Bungetrune(curio.bin);
+
block = 1;
iota = -1000000;
@@ -335,6 +354,7 @@ main(int argc, char *argv[])
frame(1);
// Process top-level declarations in phases.
+
// Phase 1: const, type, and names and types of funcs.
// This will gather all the information about types
// and methods but doesn't depend on any of it.
@@ -367,7 +387,7 @@ main(int argc, char *argv[])
errorexit();
// Phase 4: Inlining
- if (debug['l'] > 1) {
+ if(debug['l'] > 1) {
// Typecheck imported function bodies if debug['l'] > 1,
// otherwise lazily when used or re-exported.
for(l=importlist; l; l=l->next)
@@ -380,7 +400,7 @@ main(int argc, char *argv[])
errorexit();
}
- if (debug['l']) {
+ if(debug['l']) {
// Find functions that can be inlined and clone them before walk expands them.
for(l=xtop; l; l=l->next)
if(l->n->op == ODCLFUNC)
@@ -392,7 +412,7 @@ main(int argc, char *argv[])
inlcalls(l->n);
}
- // Phase 5: escape analysis.
+ // Phase 5: Escape analysis.
if(!debug['N'])
escapes(xtop);
@@ -404,21 +424,7 @@ main(int argc, char *argv[])
if(nsavederrors+nerrors == 0)
fninit(xtop);
- // Phase 6b: Compile all closures.
- // Can generate more closures, so run in batches.
- while(closures) {
- batch = closures;
- closures = nil;
- if(debug['l'])
- for(l=batch; l; l=l->next)
- inlcalls(l->n);
- if(!debug['N'])
- escapes(batch);
- for(l=batch; l; l=l->next)
- funccompile(l->n, 1);
- }
-
- // Phase 7: check external declarations.
+ // Phase 7: Check external declarations.
for(l=externdcl; l; l=l->next)
if(l->n->op == ONAME)
typecheck(&l->n, Erv);
@@ -483,7 +489,7 @@ skiptopkgdef(Biobuf *b)
if(memcmp(p, "!<arch>\n", 8) != 0)
return 0;
/* symbol table is first; skip it */
- sz = arsize(b, "__.SYMDEF");
+ sz = arsize(b, "__.GOSYMDEF");
if(sz < 0)
return 0;
Bseek(b, sz, 1);
@@ -533,7 +539,7 @@ static int
findpkg(Strlit *name)
{
Idir *p;
- char *q;
+ char *q, *race;
if(islocalname(name)) {
if(safemode)
@@ -571,10 +577,13 @@ findpkg(Strlit *name)
return 1;
}
if(goroot != nil) {
- snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s/%Z.a", goroot, goos, goarch, name);
+ race = "";
+ if(flag_race)
+ race = "_race";
+ snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s/%Z.a", goroot, goos, goarch, race, name);
if(access(namebuf, 0) >= 0)
return 1;
- snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s/%Z.%c", goroot, goos, goarch, name, thechar);
+ snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s/%Z.%c", goroot, goos, goarch, race, name, thechar);
if(access(namebuf, 0) >= 0)
return 1;
}
@@ -659,6 +668,11 @@ importfile(Val *f, int line)
strcat(cleanbuf, path->s);
cleanname(cleanbuf);
path = strlit(cleanbuf);
+
+ if(isbadimport(path)) {
+ fakeimport();
+ return;
+ }
}
if(!findpkg(path)) {
@@ -667,6 +681,16 @@ importfile(Val *f, int line)
}
importpkg = mkpkg(path);
+ // If we already saw that package, feed a dummy statement
+ // to the lexer to avoid parsing export data twice.
+ if(importpkg->imported) {
+ file = strdup(namebuf);
+ p = smprint("package %s\n$$\n", importpkg->name);
+ cannedimports(file, p);
+ return;
+ }
+ importpkg->imported = 1;
+
imp = Bopen(namebuf, OREAD);
if(imp == nil) {
yyerror("can't open import: \"%Z\": %r", f->u.sval);
@@ -767,12 +791,8 @@ static int
isfrog(int c)
{
// complain about possibly invisible control characters
- if(c < 0)
- return 1;
if(c < ' ') {
- if(c == '\n' || c== '\r' || c == '\t') // good white space
- return 0;
- return 1;
+ return !yy_isspace(c); // exclude good white space
}
if(0x7f <= c && c <= 0xa0) // DEL, unicode block including unbreakable space.
return 1;
@@ -982,6 +1002,7 @@ l0:
c1 = getc();
if(c1 == '=') {
c = LCOLAS;
+ yylval.i = lexlineno;
goto lx;
}
break;
@@ -1145,6 +1166,11 @@ l0:
case '[':
if(loophack || lstk != nil) {
h = malloc(sizeof *h);
+ if(h == nil) {
+ flusherrors();
+ yyerror("out of memory");
+ errorexit();
+ }
h->v = loophack;
h->next = lstk;
lstk = h;
@@ -1208,7 +1234,7 @@ talph:
rune = getr();
// 0xb7 · is used for internal names
if(!isalpharune(rune) && !isdigitrune(rune) && (importpkg == nil || rune != 0xb7))
- yyerror("invalid identifier character 0x%ux", rune);
+ yyerror("invalid identifier character U+%04x", rune);
cp += runetochar(cp, &rune);
} else if(!yy_isalnum(c) && c != '_')
break;
@@ -1270,12 +1296,14 @@ tnum:
continue;
if(cp == lexbuf+2)
yyerror("malformed hex constant");
+ if(c == 'p')
+ goto caseep;
goto ncu;
}
}
if(c == 'p') // 0p begins floating point zero
- goto casep;
+ goto caseep;
c1 = 0;
for(;;) {
@@ -1293,7 +1321,7 @@ tnum:
if(c == '.')
goto casedot;
if(c == 'e' || c == 'E')
- goto casee;
+ goto caseep;
if(c == 'i')
goto casei;
if(c1)
@@ -1303,10 +1331,8 @@ tnum:
dc:
if(c == '.')
goto casedot;
- if(c == 'e' || c == 'E')
- goto casee;
- if(c == 'p' || c == 'P')
- goto casep;
+ if(c == 'e' || c == 'E' || c == 'p' || c == 'P')
+ goto caseep;
if(c == 'i')
goto casei;
@@ -1342,29 +1368,8 @@ casedot:
if(c != 'e' && c != 'E')
goto caseout;
-casee:
- *cp++ = 'e';
- c = getc();
- if(c == '+' || c == '-') {
- *cp++ = c;
- c = getc();
- }
- if(!yy_isdigit(c))
- yyerror("malformed fp constant exponent");
- while(yy_isdigit(c)) {
- if(cp+10 >= ep) {
- yyerror("identifier too long");
- errorexit();
- }
- *cp++ = c;
- c = getc();
- }
- if(c == 'i')
- goto casei;
- goto caseout;
-
-casep:
- *cp++ = 'p';
+caseep:
+ *cp++ = c;
c = getc();
if(c == '+' || c == '-') {
*cp++ = c;
@@ -1430,7 +1435,12 @@ getlinepragma(void)
char *cp, *ep, *linep;
Hist *h;
- for(i=0; i<5; i++) {
+ c = getr();
+ if(c == 'g')
+ goto go;
+ if(c != 'l')
+ goto out;
+ for(i=1; i<5; i++) {
c = getr();
if(c != "line "[i])
goto out;
@@ -1478,7 +1488,35 @@ getlinepragma(void)
}
}
linehist(strdup(lexbuf), n, 0);
+ goto out;
+
+go:
+ cp = lexbuf;
+ ep = lexbuf+sizeof(lexbuf)-5;
+ *cp++ = 'g'; // already read
+ for(;;) {
+ c = getr();
+ if(c == EOF || c >= Runeself)
+ goto out;
+ if(c == '\n')
+ break;
+ if(cp < ep)
+ *cp++ = c;
+ }
+ *cp = 0;
+ ep = strchr(lexbuf, ' ');
+ if(ep != nil)
+ *ep = 0;
+ if(strcmp(lexbuf, "go:nointerface") == 0 && fieldtrack_enabled) {
+ nointerface = 1;
+ goto out;
+ }
+ if(strcmp(lexbuf, "go:noescape") == 0) {
+ noescape = 1;
+ goto out;
+ }
+
out:
return c;
}
@@ -1524,24 +1562,35 @@ yylex(void)
static int
getc(void)
{
- int c;
+ int c, c1, c2;
c = curio.peekc;
if(c != 0) {
curio.peekc = curio.peekc1;
curio.peekc1 = 0;
- if(c == '\n' && pushedio.bin == nil)
- lexlineno++;
- return c;
+ goto check;
}
if(curio.bin == nil) {
c = *curio.cp & 0xff;
if(c != 0)
curio.cp++;
- } else
+ } else {
+ loop:
c = Bgetc(curio.bin);
+ if(c == 0xef) {
+ c1 = Bgetc(curio.bin);
+ c2 = Bgetc(curio.bin);
+ if(c1 == 0xbb && c2 == 0xbf) {
+ yyerrorl(lexlineno, "Unicode (UTF-8) BOM in middle of file");
+ goto loop;
+ }
+ Bungetc(curio.bin);
+ Bungetc(curio.bin);
+ }
+ }
+check:
switch(c) {
case 0:
if(curio.bin != nil) {
@@ -1820,16 +1869,16 @@ lexinit(void)
if(etype != Txxx) {
if(etype < 0 || etype >= nelem(types))
fatal("lexinit: %s bad etype", s->name);
+ s1 = pkglookup(syms[i].name, builtinpkg);
t = types[etype];
if(t == T) {
t = typ(etype);
- t->sym = s;
+ t->sym = s1;
if(etype != TANY && etype != TSTRING)
dowidth(t);
types[etype] = t;
}
- s1 = pkglookup(syms[i].name, builtinpkg);
s1->lexical = LNAME;
s1->def = typenod(t);
continue;
@@ -1959,8 +2008,10 @@ lexfini(void)
s->lexical = lex;
etype = syms[i].etype;
- if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N)
+ if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N) {
s->def = typenod(types[etype]);
+ s->origpkg = builtinpkg;
+ }
etype = syms[i].op;
if(etype != OXXX && s->def == N) {
@@ -1968,54 +2019,68 @@ lexfini(void)
s->def->sym = s;
s->def->etype = etype;
s->def->builtin = 1;
+ s->origpkg = builtinpkg;
}
}
+ // backend-specific builtin types (e.g. int).
for(i=0; typedefs[i].name; i++) {
s = lookup(typedefs[i].name);
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(types[typedefs[i].etype]);
+ s->origpkg = builtinpkg;
+ }
}
// there's only so much table-driven we can handle.
// these are special cases.
s = lookup("byte");
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(bytetype);
-
+ s->origpkg = builtinpkg;
+ }
+
s = lookup("error");
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(errortype);
+ s->origpkg = builtinpkg;
+ }
s = lookup("rune");
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(runetype);
+ s->origpkg = builtinpkg;
+ }
s = lookup("nil");
if(s->def == N) {
v.ctype = CTNIL;
s->def = nodlit(v);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
-
+
s = lookup("iota");
if(s->def == N) {
s->def = nod(OIOTA, N, N);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
s = lookup("true");
if(s->def == N) {
s->def = nodbool(1);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
s = lookup("false");
if(s->def == N) {
s->def = nodbool(0);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
-
+
nodfp = nod(ONAME, N, N);
nodfp->type = types[TINT32];
nodfp->xoffset = 0;
@@ -2179,7 +2244,7 @@ mkpackage(char* pkgname)
{
Sym *s;
int32 h;
- char *p;
+ char *p, *q;
if(localpkg->name == nil) {
if(strcmp(pkgname, "_") == 0)
@@ -2219,6 +2284,11 @@ mkpackage(char* pkgname)
if(outfile == nil) {
p = strrchr(infile, '/');
+ if(windows) {
+ q = strrchr(infile, '\\');
+ if(q > p)
+ p = q;
+ }
if(p == nil)
p = infile;
else
diff --git a/src/cmd/gc/mparith1.c b/src/cmd/gc/mparith1.c
index 33fa90e2e..e25044a8b 100644
--- a/src/cmd/gc/mparith1.c
+++ b/src/cmd/gc/mparith1.c
@@ -43,10 +43,10 @@ mpcmpfixfix(Mpint *a, Mpint *b)
int
mpcmpfixc(Mpint *b, vlong c)
{
- Mpint a;
+ Mpint c1;
- mpmovecfix(&a, c);
- return mpcmpfixfix(&a, b);
+ mpmovecfix(&c1, c);
+ return mpcmpfixfix(b, &c1);
}
int
@@ -232,16 +232,78 @@ mppow10flt(Mpflt *a, int p)
mpmulcflt(a, 10);
}
+static void
+mphextofix(Mpint *a, char *s, int n)
+{
+ char *hexdigitp, *end, c;
+ long d;
+ int bit;
+
+ while(*s == '0') {
+ s++;
+ n--;
+ }
+
+ // overflow
+ if(4*n > Mpscale*Mpprec) {
+ a->ovf = 1;
+ return;
+ }
+
+ end = s+n-1;
+ for(hexdigitp=end; hexdigitp>=s; hexdigitp--) {
+ c = *hexdigitp;
+ if(c >= '0' && c <= '9')
+ d = c-'0';
+ else if(c >= 'A' && c <= 'F')
+ d = c-'A'+10;
+ else
+ d = c-'a'+10;
+
+ bit = 4*(end - hexdigitp);
+ while(d > 0) {
+ if(d & 1)
+ a->a[bit/Mpscale] |= (long)1 << (bit%Mpscale);
+ bit++;
+ d = d >> 1;
+ }
+ }
+}
+
//
// floating point input
-// required syntax is [+-]d*[.]d*[e[+-]d*]
+// required syntax is [+-]d*[.]d*[e[+-]d*] or [+-]0xH*[e[+-]d*]
//
void
mpatoflt(Mpflt *a, char *as)
{
Mpflt b;
- int dp, c, f, ef, ex, eb;
- char *s;
+ int dp, c, f, ef, ex, eb, base;
+ char *s, *start;
+
+ while(*as == ' ' || *as == '\t')
+ as++;
+
+ /* determine base */
+ s = as;
+ base = -1;
+ while(base == -1) {
+ switch(*s++) {
+ case '-':
+ case '+':
+ break;
+
+ case '0':
+ if(*s == 'x')
+ base = 16;
+ else
+ base = 10;
+ break;
+
+ default:
+ base = 10;
+ }
+ }
s = as;
dp = 0; /* digits after decimal point */
@@ -250,6 +312,37 @@ mpatoflt(Mpflt *a, char *as)
eb = 0; /* binary point */
mpmovecflt(a, 0.0);
+ if(base == 16) {
+ start = nil;
+ for(;;) {
+ c = *s;
+ if(c == '-') {
+ f = 1;
+ s++;
+ }
+ else if(c == '+') {
+ s++;
+ }
+ else if(c == '0' && s[1] == 'x') {
+ s += 2;
+ start = s;
+ }
+ else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
+ s++;
+ }
+ else {
+ break;
+ }
+ }
+ if(start == nil)
+ goto bad;
+
+ mphextofix(&a->val, start, s-start);
+ if(a->val.ovf)
+ goto bad;
+ a->exp = 0;
+ mpnorm(a);
+ }
for(;;) {
switch(c = *s++) {
default:
@@ -259,11 +352,13 @@ mpatoflt(Mpflt *a, char *as)
f = 1;
case ' ':
- case '\t':
- case '+':
+ case '\t':
+ case '+':
continue;
case '.':
+ if(base == 16)
+ goto bad;
dp = 1;
continue;
@@ -355,7 +450,7 @@ void
mpatofix(Mpint *a, char *as)
{
int c, f;
- char *s;
+ char *s, *s0;
s = as;
f = 0;
@@ -402,28 +497,19 @@ oct:
goto out;
hex:
- c = *s++;
+ s0 = s;
+ c = *s;
while(c) {
- if(c >= '0' && c <= '9') {
- mpmulcfix(a, 16);
- mpaddcfix(a, c-'0');
- c = *s++;
- continue;
- }
- if(c >= 'a' && c <= 'f') {
- mpmulcfix(a, 16);
- mpaddcfix(a, c+10-'a');
- c = *s++;
- continue;
- }
- if(c >= 'A' && c <= 'F') {
- mpmulcfix(a, 16);
- mpaddcfix(a, c+10-'A');
- c = *s++;
+ if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
+ s++;
+ c = *s;
continue;
}
goto bad;
}
+ mphextofix(a, s0, s-s0);
+ if(a->ovf)
+ goto bad;
out:
if(f)
@@ -439,8 +525,8 @@ int
Bconv(Fmt *fp)
{
char buf[500], *p;
- Mpint *xval, q, r, ten;
- int f;
+ Mpint *xval, q, r, ten, sixteen;
+ int f, digit;
xval = va_arg(fp->args, Mpint*);
mpmovefixfix(&q, xval);
@@ -449,15 +535,33 @@ Bconv(Fmt *fp)
f = 1;
mpnegfix(&q);
}
- mpmovecfix(&ten, 10);
p = &buf[sizeof(buf)];
*--p = 0;
- for(;;) {
- mpdivmodfixfix(&q, &r, &q, &ten);
- *--p = mpgetfix(&r) + '0';
- if(mptestfix(&q) <= 0)
- break;
+ if(fp->flags & FmtSharp) {
+ // Hexadecimal
+ mpmovecfix(&sixteen, 16);
+ for(;;) {
+ mpdivmodfixfix(&q, &r, &q, &sixteen);
+ digit = mpgetfix(&r);
+ if(digit < 10)
+ *--p = digit + '0';
+ else
+ *--p = digit - 10 + 'A';
+ if(mptestfix(&q) <= 0)
+ break;
+ }
+ *--p = 'x';
+ *--p = '0';
+ } else {
+ // Decimal
+ mpmovecfix(&ten, 10);
+ for(;;) {
+ mpdivmodfixfix(&q, &r, &q, &ten);
+ *--p = mpgetfix(&r) + '0';
+ if(mptestfix(&q) <= 0)
+ break;
+ }
}
if(f)
*--p = '-';
@@ -501,10 +605,10 @@ Fconv(Fmt *fp)
}
if(fv.exp >= 0) {
- snprint(buf, sizeof(buf), "%Bp+%d", &fv.val, fv.exp);
+ snprint(buf, sizeof(buf), "%#Bp+%d", &fv.val, fv.exp);
goto out;
}
- snprint(buf, sizeof(buf), "%Bp-%d", &fv.val, -fv.exp);
+ snprint(buf, sizeof(buf), "%#Bp-%d", &fv.val, -fv.exp);
out:
return fmtstrcpy(fp, buf);
diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c
index e45b4e0d4..b87d35b7b 100644
--- a/src/cmd/gc/obj.c
+++ b/src/cmd/gc/obj.c
@@ -59,7 +59,13 @@ dumpglobls(void)
continue;
dowidth(n->type);
- ggloblnod(n, n->type->width);
+ ggloblnod(n);
+ }
+
+ for(l=funcsyms; l; l=l->next) {
+ n = l->n;
+ dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
+ ggloblsym(n->sym, widthptr, 1, 1);
}
}
@@ -302,8 +308,8 @@ stringsym(char *s, int len)
off = 0;
// string header
- off = dsymptr(sym, off, sym, widthptr+4);
- off = duint32(sym, off, len);
+ off = dsymptr(sym, off, sym, widthptr+widthint);
+ off = duintxx(sym, off, len, widthint);
// string data
for(n=0; n<len; n+=m) {
@@ -314,7 +320,7 @@ stringsym(char *s, int len)
}
off = duint8(sym, off, 0); // terminating NUL for runtime
off = (off+widthptr-1)&~(widthptr-1); // round to pointer alignment
- ggloblsym(sym, off, 1);
+ ggloblsym(sym, off, 1, 1);
return sym;
}
diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c
index 2cab5fb95..499a4e746 100644
--- a/src/cmd/gc/order.c
+++ b/src/cmd/gc/order.c
@@ -276,11 +276,11 @@ orderstmt(Node *n, NodeList **out)
case OSELRECV2:
orderexprinplace(&r->left);
orderexprinplace(&r->ntest);
- orderexpr(&r->right->left, out);
+ orderexpr(&r->right->left, &l->n->ninit);
break;
case OSEND:
- orderexpr(&r->left, out);
- orderexpr(&r->right, out);
+ orderexpr(&r->left, &l->n->ninit);
+ orderexpr(&r->right, &l->n->ninit);
break;
}
}
diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c
index f2b75d61b..df8903baf 100644
--- a/src/cmd/gc/pgen.c
+++ b/src/cmd/gc/pgen.c
@@ -14,11 +14,12 @@ compile(Node *fn)
{
Plist *pl;
Node nod1, *n;
- Prog *ptxt;
+ Prog *plocals, *ptxt, *p, *p1;
int32 lno;
Type *t;
Iter save;
vlong oldstksize;
+ NodeList *l;
if(newproc == N) {
newproc = sysfunc("newproc");
@@ -29,16 +30,19 @@ compile(Node *fn)
throwreturn = sysfunc("throwreturn");
}
- if(fn->nbody == nil)
- return;
+ lno = setlineno(fn);
+
+ if(fn->nbody == nil) {
+ if(pure_go || memcmp(fn->nname->sym->name, "init·", 6) == 0)
+ yyerror("missing function body", fn);
+ goto ret;
+ }
saveerrors();
// set up domain for labels
clearlabels();
- lno = setlineno(fn);
-
curfn = fn;
dowidth(curfn->type);
@@ -63,6 +67,10 @@ compile(Node *fn)
walk(curfn);
if(nerrors != 0)
goto ret;
+ if(flag_race)
+ racewalk(curfn);
+ if(nerrors != 0)
+ goto ret;
continpc = P;
breakpc = P;
@@ -76,15 +84,34 @@ compile(Node *fn)
ptxt = gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1);
if(fn->dupok)
ptxt->TEXTFLAG = DUPOK;
- afunclit(&ptxt->from);
+ afunclit(&ptxt->from, curfn->nname);
ginit();
+
+ plocals = gins(ALOCALS, N, N);
+
+ for(t=curfn->paramfld; t; t=t->down)
+ gtrack(tracksym(t->type));
+
+ for(l=fn->dcl; l; l=l->next) {
+ n = l->n;
+ if(n->op != ONAME) // might be OTYPE or OLITERAL
+ continue;
+ switch(n->class) {
+ case PAUTO:
+ case PPARAM:
+ case PPARAMOUT:
+ nodconst(&nod1, types[TUINTPTR], l->n->type->width);
+ p = gins(ATYPE, l->n, &nod1);
+ p->from.gotype = ngotype(l->n);
+ break;
+ }
+ }
+
genlist(curfn->enter);
retpc = nil;
if(hasdefer || curfn->exit) {
- Prog *p1;
-
p1 = gjmp(nil);
retpc = gjmp(nil);
patch(p1, pc);
@@ -111,6 +138,7 @@ compile(Node *fn)
gclean();
if(nerrors != 0)
goto ret;
+
pc->as = ARET; // overwrite AEND
pc->lineno = lineno;
@@ -120,6 +148,10 @@ compile(Node *fn)
oldstksize = stksize;
allocauto(ptxt);
+
+ plocals->to.type = D_CONST;
+ plocals->to.offset = stksize;
+
if(0)
print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize);
@@ -177,8 +209,10 @@ allocauto(Prog* ptxt)
ll = curfn->dcl;
n = ll->n;
if (n->class == PAUTO && n->op == ONAME && !n->used) {
+ // No locals used at all
curfn->dcl = nil;
stksize = 0;
+ fixautoused(ptxt);
return;
}
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
new file mode 100644
index 000000000..bae98ec1b
--- /dev/null
+++ b/src/cmd/gc/racewalk.c
@@ -0,0 +1,579 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The racewalk pass modifies the code tree for the function as follows:
+//
+// 1. It inserts a call to racefuncenter at the beginning of each function.
+// 2. It inserts a call to racefuncexit at the end of each function.
+// 3. It inserts a call to raceread before each memory read.
+// 4. It inserts a call to racewrite before each memory write.
+//
+// The rewriting is not yet complete. Certain nodes are not rewritten
+// but should be.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+// TODO(dvyukov): do not instrument initialization as writes:
+// a := make([]int, 10)
+
+static void racewalklist(NodeList *l, NodeList **init);
+static void racewalknode(Node **np, NodeList **init, int wr, int skip);
+static int callinstr(Node **n, NodeList **init, int wr, int skip);
+static Node* uintptraddr(Node *n);
+static Node* basenod(Node *n);
+static void foreach(Node *n, void(*f)(Node*, void*), void *c);
+static void hascallspred(Node *n, void *c);
+static Node* detachexpr(Node *n, NodeList **init);
+
+// Do not instrument the following packages at all,
+// at best instrumentation would cause infinite recursion.
+static const char *omit_pkgs[] = {"runtime", "runtime/race"};
+// Only insert racefuncenter/racefuncexit into the following packages.
+// Memory accesses in the packages are either uninteresting or will cause false positives.
+static const char *noinst_pkgs[] = {"sync", "sync/atomic"};
+
+static int
+ispkgin(const char **pkgs, int n)
+{
+ int i;
+
+ if(myimportpath) {
+ for(i=0; i<n; i++) {
+ if(strcmp(myimportpath, pkgs[i]) == 0)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void
+racewalk(Node *fn)
+{
+ Node *nd;
+ Node *nodpc;
+ char s[1024];
+
+ if(ispkgin(omit_pkgs, nelem(omit_pkgs)))
+ return;
+
+ if(!ispkgin(noinst_pkgs, nelem(noinst_pkgs))) {
+ racewalklist(fn->nbody, nil);
+ // nothing interesting for race detector in fn->enter
+ racewalklist(fn->exit, nil);
+ }
+
+ // nodpc is the PC of the caller as extracted by
+ // getcallerpc. We use -widthptr(FP) for x86.
+ // BUG: this will not work on arm.
+ nodpc = nod(OXXX, nil, nil);
+ *nodpc = *nodfp;
+ nodpc->type = types[TUINTPTR];
+ nodpc->xoffset = -widthptr;
+ nd = mkcall("racefuncenter", T, nil, nodpc);
+ fn->enter = concat(list1(nd), fn->enter);
+ nd = mkcall("racefuncexit", T, nil);
+ fn->exit = list(fn->exit, nd);
+
+ if(debug['W']) {
+ snprint(s, sizeof(s), "after racewalk %S", fn->nname->sym);
+ dumplist(s, fn->nbody);
+ snprint(s, sizeof(s), "enter %S", fn->nname->sym);
+ dumplist(s, fn->enter);
+ snprint(s, sizeof(s), "exit %S", fn->nname->sym);
+ dumplist(s, fn->exit);
+ }
+}
+
+static void
+racewalklist(NodeList *l, NodeList **init)
+{
+ NodeList *instr;
+
+ for(; l; l = l->next) {
+ instr = nil;
+ racewalknode(&l->n, &instr, 0, 0);
+ if(init == nil)
+ l->n->ninit = concat(l->n->ninit, instr);
+ else
+ *init = concat(*init, instr);
+ }
+}
+
+// walkexpr and walkstmt combined
+// walks the tree and adds calls to the
+// instrumentation code to top-level (statement) nodes' init
+static void
+racewalknode(Node **np, NodeList **init, int wr, int skip)
+{
+ Node *n, *n1;
+ NodeList *l;
+ NodeList *fini;
+
+ n = *np;
+
+ if(n == N)
+ return;
+
+ if(debug['w'] > 1)
+ dump("racewalk-before", n);
+ setlineno(n);
+ if(init == nil || init == &n->ninit)
+ fatal("racewalk: bad init list");
+
+ racewalklist(n->ninit, nil);
+
+ switch(n->op) {
+ default:
+ fatal("racewalk: unknown node type %O", n->op);
+
+ case OASOP:
+ case OAS:
+ case OAS2:
+ case OAS2DOTTYPE:
+ case OAS2RECV:
+ case OAS2FUNC:
+ case OAS2MAPR:
+ racewalknode(&n->left, init, 1, 0);
+ racewalknode(&n->right, init, 0, 0);
+ goto ret;
+
+ case OCFUNC:
+ // can't matter
+ goto ret;
+
+ case OBLOCK:
+ if(n->list == nil)
+ goto ret;
+
+ switch(n->list->n->op) {
+ case OCALLFUNC:
+ case OCALLMETH:
+ case OCALLINTER:
+ // Blocks are used for multiple return function calls.
+ // x, y := f() becomes BLOCK{CALL f, AS x [SP+0], AS y [SP+n]}
+ // We don't want to instrument between the statements because it will
+ // smash the results.
+ racewalknode(&n->list->n, &n->ninit, 0, 0);
+ fini = nil;
+ racewalklist(n->list->next, &fini);
+ n->list = concat(n->list, fini);
+ break;
+
+ default:
+ // Ordinary block, for loop initialization or inlined bodies.
+ racewalklist(n->list, nil);
+ break;
+ }
+ goto ret;
+
+ case ODEFER:
+ racewalknode(&n->left, init, 0, 0);
+ goto ret;
+
+ case OPROC:
+ racewalknode(&n->left, init, 0, 0);
+ goto ret;
+
+ case OCALLINTER:
+ racewalknode(&n->left, init, 0, 0);
+ goto ret;
+
+ case OCALLFUNC:
+ racewalknode(&n->left, init, 0, 0);
+ goto ret;
+
+ case OSWITCH:
+ if(n->ntest->op == OTYPESW)
+ // TODO(dvyukov): the expression can contain calls or reads.
+ return;
+ goto ret;
+
+ case ONOT:
+ case OMINUS:
+ case OPLUS:
+ case OREAL:
+ case OIMAG:
+ racewalknode(&n->left, init, wr, 0);
+ goto ret;
+
+ case ODOTINTER:
+ racewalknode(&n->left, init, 0, 0);
+ goto ret;
+
+ case ODOT:
+ racewalknode(&n->left, init, 0, 1);
+ callinstr(&n, init, wr, skip);
+ goto ret;
+
+ case ODOTPTR: // dst = (*x).f with implicit *; otherwise it's ODOT+OIND
+ racewalknode(&n->left, init, 0, 0);
+ callinstr(&n, init, wr, skip);
+ goto ret;
+
+ case OIND: // *p
+ racewalknode(&n->left, init, 0, 0);
+ callinstr(&n, init, wr, skip);
+ goto ret;
+
+ case OLEN:
+ 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(OIND, n1, N);
+ typecheck(&n1, Erv);
+ callinstr(&n1, init, 0, skip);
+ */
+ }
+ goto ret;
+
+ case OLSH:
+ case ORSH:
+ case OAND:
+ case OANDNOT:
+ case OOR:
+ case OXOR:
+ case OSUB:
+ case OMUL:
+ case OEQ:
+ case ONE:
+ case OLT:
+ case OLE:
+ case OGE:
+ case OGT:
+ case OADD:
+ case OCOMPLEX:
+ racewalknode(&n->left, init, wr, 0);
+ racewalknode(&n->right, init, wr, 0);
+ goto ret;
+
+ case OANDAND:
+ case OOROR:
+ racewalknode(&n->left, init, wr, 0);
+ // It requires more complex tree transformation,
+ // because we don't know whether it will be executed or not.
+ //racewalknode(&n->right, init, wr, 0);
+ goto ret;
+
+ case ONAME:
+ callinstr(&n, init, wr, skip);
+ goto ret;
+
+ case OCONV:
+ racewalknode(&n->left, init, wr, 0);
+ goto ret;
+
+ case OCONVNOP:
+ racewalknode(&n->left, init, wr, 0);
+ goto ret;
+
+ 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;
+
+ case OINDEX:
+ if(!isfixedarray(n->left->type))
+ racewalknode(&n->left, init, 0, 0);
+ else if(!islvalue(n->left)) {
+ // index of unaddressable array, like Map[k][i].
+ racewalknode(&n->left, init, wr, 0);
+ racewalknode(&n->right, init, 0, 0);
+ goto ret;
+ }
+ racewalknode(&n->right, init, 0, 0);
+ if(n->left->type->etype != TSTRING)
+ callinstr(&n, init, wr, skip);
+ goto ret;
+
+ case OSLICE:
+ case OSLICEARR:
+ // Seems to only lead to double instrumentation.
+ //racewalknode(&n->left, init, 0, 0);
+ goto ret;
+
+ case OADDR:
+ racewalknode(&n->left, init, 0, 1);
+ goto ret;
+
+ case OEFACE:
+ racewalknode(&n->left, init, 0, 0);
+ racewalknode(&n->right, init, 0, 0);
+ goto ret;
+
+ // should not appear in AST by now
+ case OSEND:
+ case ORECV:
+ case OCLOSE:
+ case ONEW:
+ case OXCASE:
+ case OXFALL:
+ case OCASE:
+ case OPANIC:
+ case ORECOVER:
+ case OCONVIFACE:
+ yyerror("racewalk: %O must be lowered by now", n->op);
+ goto ret;
+
+ // just do generic traversal
+ case OFOR:
+ case OIF:
+ case OCALLMETH:
+ case ORETURN:
+ case OSELECT:
+ case OEMPTY:
+ 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:
+ case ORANGE:
+ case OTYPE:
+ case ONONAME:
+ case OINDREG:
+ case OCOM:
+ case ODOTMETH:
+ case OITAB:
+ case OEXTEND:
+ case OHMUL:
+ case OLROT:
+ case ORROTC:
+ goto ret;
+ }
+
+ret:
+ if(n->op != OBLOCK) // OBLOCK is handled above in a special way.
+ racewalklist(n->list, init);
+ l = nil;
+ racewalknode(&n->ntest, &l, 0, 0);
+ n->ninit = concat(n->ninit, l);
+ l = nil;
+ racewalknode(&n->nincr, &l, 0, 0);
+ n->ninit = concat(n->ninit, l);
+ racewalklist(n->nbody, nil);
+ racewalklist(n->nelse, nil);
+ racewalklist(n->rlist, nil);
+
+ *np = n;
+}
+
+static int
+isartificial(Node *n)
+{
+ // compiler-emitted artificial things that we do not want to instrument,
+ // cant' possibly participate in a data race.
+ if(n->op == ONAME && n->sym != S && n->sym->name != nil) {
+ if(strcmp(n->sym->name, "_") == 0)
+ return 1;
+ // autotmp's are always local
+ if(strncmp(n->sym->name, "autotmp_", sizeof("autotmp_")-1) == 0)
+ return 1;
+ // statictmp's are read-only
+ if(strncmp(n->sym->name, "statictmp_", sizeof("statictmp_")-1) == 0)
+ return 1;
+ // go.itab is accessed only by the compiler and runtime (assume safe)
+ if(n->sym->pkg && n->sym->pkg->name && strcmp(n->sym->pkg->name, "go.itab") == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static int
+callinstr(Node **np, NodeList **init, int wr, int skip)
+{
+ Node *f, *b, *n;
+ Type *t, *t1;
+ int class, res, hascalls;
+
+ n = *np;
+ //print("callinstr for %+N [ %O ] etype=%E class=%d\n",
+ // n, n->op, n->type ? n->type->etype : -1, n->class);
+
+ if(skip || n->type == T || n->type->etype >= TIDEAL)
+ return 0;
+ t = n->type;
+ if(isartificial(n))
+ return 0;
+ if(t->etype == TSTRUCT) {
+ // PARAMs w/o PHEAP are not interesting.
+ if(n->class == PPARAM || n->class == PPARAMOUT)
+ return 0;
+ res = 0;
+ hascalls = 0;
+ foreach(n, hascallspred, &hascalls);
+ if(hascalls) {
+ n = detachexpr(n, init);
+ *np = n;
+ }
+ for(t1=t->type; t1; t1=t1->down) {
+ if(t1->sym && strcmp(t1->sym->name, "_")) {
+ n = treecopy(n);
+ f = nod(OXDOT, n, newname(t1->sym));
+ f->type = t1;
+ if(f->type->etype == TFIELD)
+ f->type = f->type->type;
+ if(callinstr(&f, init, wr, 0)) {
+ typecheck(&f, Erv);
+ res = 1;
+ }
+ }
+ }
+ return res;
+ }
+
+ b = basenod(n);
+ // it skips e.g. stores to ... parameter array
+ if(isartificial(b))
+ return 0;
+ class = b->class;
+ // BUG: we _may_ want to instrument PAUTO sometimes
+ // e.g. if we've got a local variable/method receiver
+ // that has got a pointer inside. Whether it points to
+ // the heap or not is impossible to know at compile time
+ if((class&PHEAP) || class == PPARAMREF || class == PEXTERN
+ || b->type->etype == TARRAY || b->op == ODOTPTR || b->op == OIND || b->op == OXDOT) {
+ hascalls = 0;
+ foreach(n, hascallspred, &hascalls);
+ if(hascalls) {
+ n = detachexpr(n, init);
+ *np = n;
+ }
+ n = treecopy(n);
+ f = mkcall(wr ? "racewrite" : "raceread", T, init, uintptraddr(n));
+ *init = list(*init, f);
+ return 1;
+ }
+ return 0;
+}
+
+static Node*
+uintptraddr(Node *n)
+{
+ Node *r;
+
+ r = nod(OADDR, n, N);
+ r = conv(r, types[TUNSAFEPTR]);
+ r = conv(r, types[TUINTPTR]);
+ return r;
+}
+
+static Node*
+basenod(Node *n)
+{
+ for(;;) {
+ if(n->op == ODOT || n->op == OXDOT || n->op == OCONVNOP || n->op == OCONV || n->op == OPAREN) {
+ n = n->left;
+ continue;
+ }
+ if(n->op == OINDEX) {
+ n = n->left;
+ continue;
+ }
+ break;
+ }
+ return n;
+}
+
+static Node*
+detachexpr(Node *n, NodeList **init)
+{
+ Node *addr, *as, *ind, *l;
+
+ addr = nod(OADDR, n, N);
+ l = temp(ptrto(n->type));
+ as = nod(OAS, l, addr);
+ typecheck(&as, Etop);
+ walkexpr(&as, init);
+ *init = list(*init, as);
+ ind = nod(OIND, l, N);
+ typecheck(&ind, Erv);
+ walkexpr(&ind, init);
+ return ind;
+}
+
+static void
+foreachnode(Node *n, void(*f)(Node*, void*), void *c)
+{
+ if(n)
+ f(n, c);
+}
+
+static void
+foreachlist(NodeList *l, void(*f)(Node*, void*), void *c)
+{
+ for(; l; l = l->next)
+ foreachnode(l->n, f, c);
+}
+
+static void
+foreach(Node *n, void(*f)(Node*, void*), void *c)
+{
+ foreachlist(n->ninit, f, c);
+ foreachnode(n->left, f, c);
+ foreachnode(n->right, f, c);
+ foreachlist(n->list, f, c);
+ foreachnode(n->ntest, f, c);
+ foreachnode(n->nincr, f, c);
+ foreachlist(n->nbody, f, c);
+ foreachlist(n->nelse, f, c);
+ foreachlist(n->rlist, f, c);
+}
+
+static void
+hascallspred(Node *n, void *c)
+{
+ switch(n->op) {
+ case OCALL:
+ case OCALLFUNC:
+ case OCALLMETH:
+ case OCALLINTER:
+ (*(int*)c)++;
+ }
+}
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c
index d301e4e4f..50c4617c0 100644
--- a/src/cmd/gc/range.c
+++ b/src/cmd/gc/range.c
@@ -72,6 +72,15 @@ typecheckrange(Node *n)
if(n->list->next)
v2 = n->list->next->n;
+ // this is not only a optimization but also a requirement in the spec.
+ // "if the second iteration variable is the blank identifier, the range
+ // clause is equivalent to the same clause with only the first variable
+ // present."
+ if(isblank(v2)) {
+ n->list = list1(v1);
+ v2 = N;
+ }
+
if(v1->defn == n)
v1->type = t1;
else if(v1->type != T && assignop(t1, v1->type, &why) == 0)
@@ -145,7 +154,7 @@ walkrange(Node *n)
if(v2) {
hp = temp(ptrto(n->type->type));
tmp = nod(OINDEX, ha, nodintconst(0));
- tmp->etype = 1; // no bounds check
+ tmp->bounded = 1;
init = list(init, nod(OAS, hp, nod(OADDR, tmp, N)));
}
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index 62759bcba..b8eb79938 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -5,6 +5,7 @@
#include <u.h>
#include <libc.h>
#include "go.h"
+#include "../../pkg/runtime/mgc0.h"
/*
* runtime interface and reflection data structures
@@ -14,12 +15,13 @@ static NodeList* signatlist;
static Sym* dtypesym(Type*);
static Sym* weaktypesym(Type*);
static Sym* dalgsym(Type*);
+static Sym* dgcsym(Type*);
static int
sigcmp(Sig *a, Sig *b)
{
int i;
-
+
i = strcmp(a->name, b->name);
if(i != 0)
return i;
@@ -130,7 +132,12 @@ methodfunc(Type *f, Type *receiver)
out = list(out, d);
}
- return functype(N, in, out);
+ t = functype(N, in, out);
+ if(f->nname) {
+ // Link to name of original method function.
+ t->nname = f->nname;
+ }
+ return t;
}
/*
@@ -165,6 +172,8 @@ methods(Type *t)
fatal("non-method on %T method %S %T\n", mt, f->sym, f);
if (!getthisx(f->type)->type)
fatal("receiver with no type on %T method %S %T\n", mt, f->sym, f);
+ if(f->nointerface)
+ continue;
method = f->sym;
if(method == nil)
@@ -203,22 +212,26 @@ methods(Type *t)
// but we can generate more efficient code
// using genembedtramp if all that is necessary
// is a pointer adjustment and a JMP.
+ compiling_wrappers = 1;
if(isptr[it->etype] && isptr[this->etype]
&& f->embedded && !isifacemethod(f->type))
genembedtramp(it, f, a->isym, 1);
else
genwrapper(it, f, a->isym, 1);
+ compiling_wrappers = 0;
}
}
if(!(a->tsym->flags & SymSiggen)) {
a->tsym->flags |= SymSiggen;
if(!eqtype(this, t)) {
+ compiling_wrappers = 1;
if(isptr[t->etype] && isptr[this->etype]
&& f->embedded && !isifacemethod(f->type))
genembedtramp(t, f, a->tsym, 0);
else
genwrapper(t, f, a->tsym, 0);
+ compiling_wrappers = 0;
}
}
}
@@ -262,12 +275,12 @@ imethods(Type *t)
else
last->link = a;
last = a;
-
+
// Compiler can only refer to wrappers for
// named interface types.
if(t->sym == S)
continue;
-
+
// NOTE(rsc): Perhaps an oversight that
// IfaceType.Method is not in the reflect data.
// Generate the method body, so that compiled
@@ -287,7 +300,7 @@ dimportpath(Pkg *p)
static Pkg *gopkg;
char *nam;
Node *n;
-
+
if(p->pathsym != S)
return;
@@ -303,9 +316,9 @@ dimportpath(Pkg *p)
n->class = PEXTERN;
n->xoffset = 0;
p->pathsym = n->sym;
-
+
gdatastring(n, p->path);
- ggloblsym(n->sym, types[TSTRING]->width, 1);
+ ggloblsym(n->sym, types[TSTRING]->width, 1, 1);
}
static int
@@ -319,7 +332,7 @@ dgopkgpath(Sym *s, int ot, Pkg *pkg)
// that imports this one directly defines the symbol.
if(pkg == localpkg) {
static Sym *ns;
-
+
if(ns == nil)
ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
return dsymptr(s, ot, ns, 0);
@@ -343,7 +356,7 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
m = methods(t);
if(t->sym == nil && m == nil)
return off;
-
+
// fill in *extraType pointer in header
dsymptr(sym, ptroff, sym, off);
@@ -367,9 +380,9 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
}
// slice header
- ot = dsymptr(s, ot, s, ot + widthptr + 2*4);
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
+ ot = dsymptr(s, ot, s, ot + widthptr + 2*widthint);
+ ot = duintxx(s, ot, n, widthint);
+ ot = duintxx(s, ot, n, widthint);
// methods
for(a=m; a; a=a->link) {
@@ -419,7 +432,7 @@ enum {
KindString,
KindStruct,
KindUnsafePointer,
-
+
KindNoPointers = 1<<7,
};
@@ -454,19 +467,6 @@ kinds[] =
[TUNSAFEPTR] = KindUnsafePointer,
};
-static Sym*
-typestruct(Type *t)
-{
- // We use a weak reference to the reflect type
- // to avoid requiring package reflect in every binary.
- // If package reflect is available, the interface{} holding
- // a runtime type will contain a *reflect.commonType.
- // Otherwise it will use a nil type word but still be usable
- // by package runtime (because we always use the memory
- // after the interface value, not the interface value itself).
- return pkglookup("*reflect.commonType", weaktypepkg);
-}
-
int
haspointers(Type *t)
{
@@ -521,6 +521,9 @@ dcommontype(Sym *s, int ot, Type *t)
Sym *sptr, *algsym;
static Sym *algarray;
char *p;
+
+ if(ot != 0)
+ fatal("dcommontype %d", ot);
sizeofAlg = 4*widthptr;
if(algarray == nil)
@@ -536,31 +539,34 @@ dcommontype(Sym *s, int ot, Type *t)
else
sptr = weaktypesym(ptrto(t));
- // empty interface pointing at this type.
- // all the references that we emit are *interface{};
- // they point here.
- ot = rnd(ot, widthptr);
- ot = dsymptr(s, ot, typestruct(t), 0);
- ot = dsymptr(s, ot, s, 2*widthptr);
-
// ../../pkg/reflect/type.go:/^type.commonType
// actual type structure
// type commonType struct {
- // size uintptr;
- // hash uint32;
- // alg uint8;
- // align uint8;
- // fieldAlign uint8;
- // kind uint8;
- // string *string;
- // *extraType;
- // ptrToThis *Type
+ // size uintptr
+ // hash uint32
+ // _ uint8
+ // align uint8
+ // fieldAlign uint8
+ // kind uint8
+ // alg unsafe.Pointer
+ // gc unsafe.Pointer
+ // string *string
+ // *extraType
+ // ptrToThis *Type
// }
ot = duintptr(s, ot, t->width);
ot = duint32(s, ot, typehash(t));
ot = duint8(s, ot, 0); // unused
+
+ // runtime (and common sense) expects alignment to be a power of two.
+ i = t->align;
+ if(i == 0)
+ i = 1;
+ if((i&(i-1)) != 0)
+ fatal("invalid alignment %d for %T", t->align, t);
ot = duint8(s, ot, t->align); // align
ot = duint8(s, ot, t->align); // fieldAlign
+
i = kinds[t->etype];
if(t->etype == TARRAY && t->bound < 0)
i = KindSlice;
@@ -571,11 +577,12 @@ dcommontype(Sym *s, int ot, Type *t)
ot = dsymptr(s, ot, algarray, alg*sizeofAlg);
else
ot = dsymptr(s, ot, algsym, 0);
+ ot = dsymptr(s, ot, dgcsym(t), 0); // gc
p = smprint("%-uT", t);
//print("dcommontype: %s\n", p);
ot = dgostringptr(s, ot, p); // string
free(p);
-
+
// skip pointer to extraType,
// which follows the rest of this type structure.
// caller will fill in if needed.
@@ -600,6 +607,39 @@ typesym(Type *t)
}
Sym*
+tracksym(Type *t)
+{
+ char *p;
+ Sym *s;
+
+ p = smprint("%-T.%s", t->outer, t->sym->name);
+ s = pkglookup(p, trackpkg);
+ free(p);
+ return s;
+}
+
+Sym*
+typelinksym(Type *t)
+{
+ char *p;
+ Sym *s;
+
+ // %-uT is what the generated Type's string field says.
+ // It uses (ambiguous) package names instead of import paths.
+ // %-T is the complete, unambiguous type name.
+ // We want the types to end up sorted by string field,
+ // so use that first in the name, and then add :%-T to
+ // disambiguate. The names are a little long but they are
+ // discarded by the linker and do not end up in the symbol
+ // table of the final binary.
+ p = smprint("%-uT/%-T", t, t);
+ s = pkglookup(p, typelinkpkg);
+ //print("typelinksym: %s -> %+S\n", p, s);
+ free(p);
+ return s;
+}
+
+Sym*
typesymprefix(char *prefix, Type *t)
{
char *p;
@@ -612,8 +652,8 @@ typesymprefix(char *prefix, Type *t)
return s;
}
-Node*
-typename(Type *t)
+Sym*
+typenamesym(Type *t)
{
Sym *s;
Node *n;
@@ -634,7 +674,16 @@ typename(Type *t)
signatlist = list(signatlist, typenod(t));
}
+ return s->def->sym;
+}
+
+Node*
+typename(Type *t)
+{
+ Sym *s;
+ Node *n;
+ s = typenamesym(t);
n = nod(OADDR, s->def, N);
n->type = ptrto(s->def->type);
n->addable = 1;
@@ -660,10 +709,16 @@ static Sym*
dtypesym(Type *t)
{
int ot, xt, n, isddd, dupok;
- Sym *s, *s1, *s2;
+ Sym *s, *s1, *s2, *slink;
Sig *a, *m;
Type *t1, *tbase, *t2;
+ // Replace byte, rune aliases with real type.
+ // They've been separate internally to make error messages
+ // better, but we have to merge them in the reflect tables.
+ if(t == bytetype || t == runetype)
+ t = types[t->etype];
+
if(isideal(t))
fatal("dtypesym %T", t);
@@ -680,7 +735,7 @@ dtypesym(Type *t)
tbase = t->type;
dupok = tbase->sym == S;
- if(compiling_runtime &&
+ if(compiling_runtime &&
(tbase == types[tbase->etype] ||
tbase == bytetype ||
tbase == runetype ||
@@ -751,13 +806,13 @@ ok:
// two slice headers: in and out.
ot = rnd(ot, widthptr);
- ot = dsymptr(s, ot, s, ot+2*(widthptr+2*4));
+ ot = dsymptr(s, ot, s, ot+2*(widthptr+2*widthint));
n = t->thistuple + t->intuple;
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
- ot = dsymptr(s, ot, s, ot+1*(widthptr+2*4)+n*widthptr);
- ot = duint32(s, ot, t->outtuple);
- ot = duint32(s, ot, t->outtuple);
+ ot = duintxx(s, ot, n, widthint);
+ ot = duintxx(s, ot, n, widthint);
+ ot = dsymptr(s, ot, s, ot+1*(widthptr+2*widthint)+n*widthptr);
+ ot = duintxx(s, ot, t->outtuple, widthint);
+ ot = duintxx(s, ot, t->outtuple, widthint);
// slice data
for(t1=getthisx(t)->type; t1; t1=t1->down, n++)
@@ -779,9 +834,9 @@ ok:
// ../../pkg/runtime/type.go:/InterfaceType
ot = dcommontype(s, ot, t);
xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s, ot+widthptr+2*4);
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
+ ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
+ ot = duintxx(s, ot, n, widthint);
+ ot = duintxx(s, ot, n, widthint);
for(a=m; a; a=a->link) {
// ../../pkg/runtime/type.go:/imethod
ot = dgostringptr(s, ot, a->name);
@@ -824,9 +879,9 @@ ok:
}
ot = dcommontype(s, ot, t);
xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s, ot+widthptr+2*4);
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
+ ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
+ ot = duintxx(s, ot, n, widthint);
+ ot = duintxx(s, ot, n, widthint);
for(t1=t->type; t1!=T; t1=t1->down) {
// ../../pkg/runtime/type.go:/structField
if(t1->sym && !t1->embedded) {
@@ -837,7 +892,10 @@ ok:
ot = dgopkgpath(s, ot, t1->sym->pkg);
} else {
ot = dgostringptr(s, ot, nil);
- ot = dgostringptr(s, ot, nil);
+ if(t1->type->sym != S && t1->type->sym->pkg == builtinpkg)
+ ot = dgopkgpath(s, ot, localpkg);
+ else
+ ot = dgostringptr(s, ot, nil);
}
ot = dsymptr(s, ot, dtypesym(t1->type), 0);
ot = dgostrlitptr(s, ot, t1->note);
@@ -846,7 +904,24 @@ ok:
break;
}
ot = dextratype(s, ot, t, xt);
- ggloblsym(s, ot, dupok);
+ ggloblsym(s, ot, dupok, 1);
+
+ // generate typelink.foo pointing at s = type.foo.
+ // The linker will leave a table of all the typelinks for
+ // types in the binary, so reflect can find them.
+ // We only need the link for unnamed composites that
+ // we want be able to find.
+ if(t->sym == S) {
+ switch(t->etype) {
+ case TARRAY:
+ case TCHAN:
+ case TMAP:
+ slink = typelinksym(t);
+ dsymptr(slink, 0, s, 0);
+ ggloblsym(slink, widthptr, dupok, 1);
+ }
+ }
+
return s;
}
@@ -899,12 +974,14 @@ dumptypestructs(void)
// emit type structs for error and func(error) string.
// The latter is the type of an auto-generated wrapper.
dtypesym(ptrto(errortype));
- dtypesym(functype(nil,
+ dtypesym(functype(nil,
list1(nod(ODCLFIELD, N, typenod(errortype))),
list1(nod(ODCLFIELD, N, typenod(types[TSTRING])))));
-
+
// add paths for runtime and main, which 6l imports implicitly.
dimportpath(runtimepkg);
+ if(flag_race)
+ dimportpath(racepkg);
dimportpath(mkpkg(strlit("main")));
}
}
@@ -944,7 +1021,180 @@ dalgsym(Type *t)
break;
}
- ggloblsym(s, ot, 1);
+ ggloblsym(s, ot, 1, 1);
return s;
}
+static int
+dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
+{
+ Type *t1;
+ vlong o, off2, fieldoffset;
+
+ if(t->align > 0 && (*off % t->align) != 0)
+ fatal("dgcsym1: invalid initial alignment, %T", t);
+
+ switch(t->etype) {
+ case TINT8:
+ case TUINT8:
+ case TINT16:
+ case TUINT16:
+ case TINT32:
+ case TUINT32:
+ case TINT64:
+ case TUINT64:
+ case TINT:
+ case TUINT:
+ case TUINTPTR:
+ case TBOOL:
+ case TFLOAT32:
+ case TFLOAT64:
+ case TCOMPLEX64:
+ case TCOMPLEX128:
+ *off += t->width;
+ break;
+
+ case TPTR32:
+ case TPTR64:
+ if(*off % widthptr != 0)
+ fatal("dgcsym1: invalid alignment, %T", t);
+ if(!haspointers(t->type) || t->type->etype == TUINT8) {
+ ot = duintptr(s, ot, GC_APTR);
+ ot = duintptr(s, ot, *off);
+ } else {
+ ot = duintptr(s, ot, GC_PTR);
+ ot = duintptr(s, ot, *off);
+ ot = dsymptr(s, ot, dgcsym(t->type), 0);
+ }
+ *off += t->width;
+ break;
+
+ case TCHAN:
+ case TUNSAFEPTR:
+ case TFUNC:
+ if(*off % widthptr != 0)
+ fatal("dgcsym1: invalid alignment, %T", t);
+ ot = duintptr(s, ot, GC_APTR);
+ ot = duintptr(s, ot, *off);
+ *off += t->width;
+ break;
+
+ // struct Hmap*
+ case TMAP:
+ if(*off % widthptr != 0)
+ fatal("dgcsym1: invalid alignment, %T", t);
+ ot = duintptr(s, ot, GC_MAP_PTR);
+ ot = duintptr(s, ot, *off);
+ ot = dsymptr(s, ot, dtypesym(t), 0);
+ *off += t->width;
+ break;
+
+ // struct { byte *str; int32 len; }
+ case TSTRING:
+ if(*off % widthptr != 0)
+ fatal("dgcsym1: invalid alignment, %T", t);
+ ot = duintptr(s, ot, GC_STRING);
+ ot = duintptr(s, ot, *off);
+ *off += t->width;
+ break;
+
+ // struct { Itab* tab; void* data; }
+ // struct { Type* type; void* data; } // When isnilinter(t)==true
+ case TINTER:
+ if(*off % widthptr != 0)
+ fatal("dgcsym1: invalid alignment, %T", t);
+ if(isnilinter(t)) {
+ ot = duintptr(s, ot, GC_EFACE);
+ ot = duintptr(s, ot, *off);
+ } else {
+ ot = duintptr(s, ot, GC_IFACE);
+ ot = duintptr(s, ot, *off);
+ }
+ *off += t->width;
+ break;
+
+ case TARRAY:
+ if(t->bound < -1)
+ fatal("dgcsym1: invalid bound, %T", t);
+ if(isslice(t)) {
+ // struct { byte* array; uint32 len; uint32 cap; }
+ if(*off % widthptr != 0)
+ fatal("dgcsym1: invalid alignment, %T", t);
+ if(t->type->width != 0) {
+ ot = duintptr(s, ot, GC_SLICE);
+ ot = duintptr(s, ot, *off);
+ ot = dsymptr(s, ot, dgcsym(t->type), 0);
+ } else {
+ ot = duintptr(s, ot, GC_APTR);
+ ot = duintptr(s, ot, *off);
+ }
+ *off += t->width;
+ } 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(stack_size < GC_STACK_CAPACITY) {
+ ot = duintptr(s, ot, GC_ARRAY_START); // a stack push during GC
+ ot = duintptr(s, ot, *off);
+ ot = duintptr(s, ot, t->bound);
+ ot = duintptr(s, ot, t->type->width);
+ off2 = 0;
+ ot = dgcsym1(s, ot, t->type, &off2, stack_size+1); // recursive call of dgcsym1
+ ot = duintptr(s, ot, GC_ARRAY_NEXT); // a stack pop during GC
+ } else {
+ ot = duintptr(s, ot, GC_REGION);
+ ot = duintptr(s, ot, *off);
+ ot = duintptr(s, ot, t->width);
+ ot = dsymptr(s, ot, dgcsym(t), 0);
+ }
+ *off += t->width;
+ }
+ }
+ break;
+
+ case TSTRUCT:
+ o = 0;
+ for(t1=t->type; t1!=T; t1=t1->down) {
+ fieldoffset = t1->width;
+ *off += fieldoffset - o;
+ ot = dgcsym1(s, ot, t1->type, off, stack_size); // recursive call of dgcsym1
+ o = fieldoffset + t1->type->width;
+ }
+ *off += t->width - o;
+ break;
+
+ default:
+ fatal("dgcsym1: unexpected type %T", t);
+ }
+
+ return ot;
+}
+
+static Sym*
+dgcsym(Type *t)
+{
+ int ot;
+ vlong off;
+ Sym *s;
+
+ s = typesymprefix(".gc", t);
+ if(s->flags & SymGcgen)
+ return s;
+ s->flags |= SymGcgen;
+
+ ot = 0;
+ off = 0;
+ ot = duintptr(s, ot, t->width);
+ ot = dgcsym1(s, ot, t, &off, 0);
+ ot = duintptr(s, ot, GC_END);
+ ggloblsym(s, ot, 1, 1);
+
+ if(t->align > 0)
+ off = rnd(off, t->align);
+ if(off != t->width)
+ fatal("dgcsym: off=%lld, size=%lld, type %T", off, t->width, t);
+
+ return s;
+}
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index 15a61d9ef..c49d05c5c 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -45,8 +45,7 @@ func appendslice(typ *byte, x any, y []any) any
func appendstr(typ *byte, x []byte, y string) []byte
func cmpstring(string, string) int
-func slicestring(string, int, int) string
-func slicestring1(string, int) string
+func eqstring(string, string) bool
func intstring(int64) string
func slicebytetostring([]byte) string
func slicerunetostring([]rune) string
@@ -54,14 +53,15 @@ func stringtoslicebyte(string) []byte
func stringtoslicerune(string) []rune
func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv rune)
-func copy(to any, fr any, wid uint32) int
+func copy(to any, fr any, wid uintptr) int
func slicestringcopy(to any, fr any) int
// interface conversions
+func typ2Itab(typ *byte, typ2 *byte, cache **byte) (ret *byte)
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
func convT2E(typ *byte, elem any) (ret any)
-func convT2I(typ *byte, typ2 *byte, elem any) (ret any)
+func convT2I(typ *byte, typ2 *byte, cache **byte, elem any) (ret any)
// interface type assertions x.(T)
func assertE2E(typ *byte, iface any) (ret any)
@@ -76,6 +76,8 @@ func assertI2I(typ *byte, iface any) (ret any)
func assertI2I2(typ *byte, iface any) (ret any, ok bool)
func assertI2T(typ *byte, iface any) (ret any)
func assertI2T2(typ *byte, iface any) (ret any, ok bool)
+func assertI2TOK(typ *byte, iface any) (ok bool)
+func assertE2TOK(typ *byte, iface any) (ok bool)
func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
@@ -89,7 +91,6 @@ func makemap(mapType *byte, hint int64) (hmap map[any]any)
func mapaccess1(mapType *byte, hmap map[any]any, key any) (val any)
func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool)
func mapassign1(mapType *byte, hmap map[any]any, key any, val any)
-func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool)
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
func mapdelete(mapType *byte, hmap map[any]any, key any)
func mapiternext(hiter *any)
@@ -107,7 +108,7 @@ func selectnbsend(chanType *byte, hchan chan<- any, elem any) bool
func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool
-func newselect(size int) (sel *byte)
+func newselect(size int32) (sel *byte)
func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool)
func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
func selectrecv2(sel *byte, hchan <-chan any, elem *any, received *bool) (selected bool)
@@ -117,11 +118,6 @@ func block()
func makeslice(typ *byte, nel int64, cap int64) (ary []any)
func growslice(typ *byte, old []any, n int64) (ary []any)
-func sliceslice1(old []any, lb uint64, width uint64) (ary []any)
-func sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any)
-func slicearray(old *any, nel uint64, lb uint64, hb uint64, width uint64) (ary []any)
-
-func closure() // has args, but compiler fills in
func memequal(eq *bool, size uintptr, x, y *any)
func memequal8(eq *bool, size uintptr, x, y *any)
@@ -141,3 +137,9 @@ func int64tofloat64(int64) float64
func uint64tofloat64(uint64) float64
func complex128div(num complex128, den complex128) (quo complex128)
+
+// race detection
+func racefuncenter(uintptr)
+func racefuncexit()
+func raceread(uintptr)
+func racewrite(uintptr)
diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c
index 8ace1d4ee..cd3de8c7b 100644
--- a/src/cmd/gc/select.c
+++ b/src/cmd/gc/select.c
@@ -62,7 +62,7 @@ typecheckselect(Node *sel)
case OAS2RECV:
// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
- if(n->right->op != ORECV) {
+ if(n->rlist->n->op != ORECV) {
yyerror("select assignment must have receive on right hand side");
break;
}
@@ -70,6 +70,7 @@ typecheckselect(Node *sel)
n->left = n->list->n;
n->ntest = n->list->next->n;
n->right = n->rlist->n;
+ n->rlist = nil;
break;
case ORECV:
@@ -146,7 +147,7 @@ walkselect(Node *sel)
a = nod(OAS2, N, N);
a->list = n->list;
- a->rlist = n->rlist;
+ a->rlist = list1(n->right);
n = a;
typecheck(&n, Etop);
break;
@@ -296,15 +297,15 @@ walkselect(Node *sel)
setlineno(cas);
n = cas->left;
r = nod(OIF, N, N);
- r->nbody = cas->ninit;
+ r->ninit = cas->ninit;
cas->ninit = nil;
if(n != nil) {
- r->nbody = concat(r->nbody, n->ninit);
+ r->ninit = concat(r->ninit, n->ninit);
n->ninit = nil;
}
if(n == nil) {
// selectdefault(sel *byte);
- r->ntest = mkcall("selectdefault", types[TBOOL], &init, var);
+ r->ntest = mkcall("selectdefault", types[TBOOL], &r->ninit, var);
} else {
switch(n->op) {
default:
@@ -312,25 +313,25 @@ walkselect(Node *sel)
case OSEND:
// selectsend(sel *byte, hchan *chan any, elem *any) (selected bool);
- n->left = safeexpr(n->left, &r->ninit);
+ n->left = localexpr(safeexpr(n->left, &r->ninit), n->left->type, &r->ninit);
n->right = localexpr(n->right, n->left->type->type, &r->ninit);
n->right = nod(OADDR, n->right, N);
n->right->etype = 1; // pointer does not escape
typecheck(&n->right, Erv);
r->ntest = mkcall1(chanfn("selectsend", 2, n->left->type), types[TBOOL],
- &init, var, n->left, n->right);
+ &r->ninit, var, n->left, n->right);
break;
case OSELRECV:
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
r->ntest = mkcall1(chanfn("selectrecv", 2, n->right->left->type), types[TBOOL],
- &init, var, n->right->left, n->left);
+ &r->ninit, var, n->right->left, n->left);
break;
case OSELRECV2:
// selectrecv2(sel *byte, hchan *chan any, elem *any, received *bool) (selected bool);
r->ntest = mkcall1(chanfn("selectrecv2", 2, n->right->left->type), types[TBOOL],
- &init, var, n->right->left, n->left, n->ntest);
+ &r->ninit, var, n->right->left, n->left, n->ntest);
break;
}
}
diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c
index c8796f8b7..353fc00ce 100644
--- a/src/cmd/gc/sinit.c
+++ b/src/cmd/gc/sinit.c
@@ -37,6 +37,12 @@ init1(Node *n, NodeList **out)
for(l=n->list; l; l=l->next)
init1(l->n, out);
+ if(n->left && n->type && n->left->op == OTYPE && n->class == PFUNC) {
+ // Methods called as Type.Method(receiver, ...).
+ // Definitions for method expressions are stored in type->nname.
+ init1(n->type->nname, out);
+ }
+
if(n->op != ONAME)
return;
switch(n->class) {
@@ -78,6 +84,11 @@ init1(Node *n, NodeList **out)
}
n->initorder = InitPending;
l = malloc(sizeof *l);
+ if(l == nil) {
+ flusherrors();
+ yyerror("out of memory");
+ errorexit();
+ }
l->next = initlist;
l->n = n;
l->end = nil;
@@ -97,6 +108,13 @@ init1(Node *n, NodeList **out)
case OAS:
if(n->defn->left != n)
goto bad;
+ if(isblank(n->defn->left) && candiscard(n->defn->right)) {
+ n->defn->op = OEMPTY;
+ n->defn->left = N;
+ n->defn->right = N;
+ break;
+ }
+
/*
n->defn->dodata = 1;
init1(n->defn->right, out);
@@ -167,6 +185,11 @@ init2(Node *n, NodeList **out)
init2list(n->rlist, out);
init2list(n->nbody, out);
init2list(n->nelse, out);
+
+ if(n->op == OCLOSURE)
+ init2list(n->closure->nbody, out);
+ if(n->op == ODOTMETH)
+ init2(n->type->nname, out);
}
static void
@@ -291,9 +314,9 @@ staticcopy(Node *l, Node *r, NodeList **out)
n1.xoffset = l->xoffset + Array_array;
gdata(&n1, nod(OADDR, a, N), widthptr);
n1.xoffset = l->xoffset + Array_nel;
- gdata(&n1, r->right, 4);
+ gdata(&n1, r->right, widthint);
n1.xoffset = l->xoffset + Array_cap;
- gdata(&n1, r->right, 4);
+ gdata(&n1, r->right, widthint);
return 1;
}
// fall through
@@ -394,9 +417,9 @@ staticassign(Node *l, Node *r, NodeList **out)
n1.xoffset = l->xoffset + Array_array;
gdata(&n1, nod(OADDR, a, N), widthptr);
n1.xoffset = l->xoffset + Array_nel;
- gdata(&n1, r->right, 4);
+ gdata(&n1, r->right, widthint);
n1.xoffset = l->xoffset + Array_cap;
- gdata(&n1, r->right, 4);
+ gdata(&n1, r->right, widthint);
// Fall through to init underlying array.
l = a;
}
@@ -747,7 +770,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
index = r->left;
value = r->right;
a = nod(OINDEX, var, index);
- a->etype = 1; // no bounds checking
+ a->bounded = 1;
// TODO need to check bounds?
switch(value->op) {
@@ -879,11 +902,11 @@ ctxt = 0;
index = temp(types[TINT]);
a = nod(OINDEX, vstat, index);
- a->etype = 1; // no bounds checking
+ a->bounded = 1;
a = nod(ODOT, a, newname(symb));
r = nod(OINDEX, vstat, index);
- r->etype = 1; // no bounds checking
+ r->bounded = 1;
r = nod(ODOT, r, newname(syma));
r = nod(OINDEX, var, r);
@@ -930,7 +953,7 @@ void
anylit(int ctxt, Node *n, Node *var, NodeList **init)
{
Type *t;
- Node *a, *vstat;
+ Node *a, *vstat, *r;
t = n->type;
switch(n->op) {
@@ -941,7 +964,14 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
if(!isptr[t->etype])
fatal("anylit: not ptr");
- a = nod(OAS, var, callnew(t->type));
+ r = nod(ONEW, N, N);
+ r->typecheck = 1;
+ r->type = t;
+ r->esc = n->esc;
+ walkexpr(&r, init);
+
+ a = nod(OAS, var, r);
+
typecheck(&a, Etop);
*init = list(*init, a);
@@ -1223,11 +1253,11 @@ slice:
gdata(&nam, nl, types[tptr]->width);
nam.xoffset += Array_nel-Array_array;
- nodconst(&nod1, types[TINT32], nr->type->bound);
- gdata(&nam, &nod1, types[TINT32]->width);
+ nodconst(&nod1, types[TINT], nr->type->bound);
+ gdata(&nam, &nod1, widthint);
nam.xoffset += Array_cap-Array_nel;
- gdata(&nam, &nod1, types[TINT32]->width);
+ gdata(&nam, &nod1, widthint);
goto yes;
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index bd53520df..c53eaf285 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -142,18 +142,32 @@ yyerror(char *fmt, ...)
if(debug['x'])
print("yyerror: yystate=%d yychar=%d\n", yystate, yychar);
+ // An unexpected EOF caused a syntax error. Use the previous
+ // line number since getc generated a fake newline character.
+ if(curio.eofnl)
+ lexlineno = prevlineno;
+
// only one syntax error per line
if(lastsyntax == lexlineno)
return;
lastsyntax = lexlineno;
-
- if(strstr(fmt, "{ or {")) {
+
+ if(strstr(fmt, "{ or {") || strstr(fmt, " or ?") || strstr(fmt, " or @")) {
// The grammar has { and LBRACE but both show up as {.
// Rewrite syntax error referring to "{ or {" to say just "{".
strecpy(buf, buf+sizeof buf, fmt);
p = strstr(buf, "{ or {");
if(p)
memmove(p+1, p+6, strlen(p+6)+1);
+
+ // The grammar has ? and @ but only for reading imports.
+ // Silence them in ordinary errors.
+ p = strstr(buf, " or ?");
+ if(p)
+ memmove(p, p+5, strlen(p+5)+1);
+ p = strstr(buf, " or @");
+ if(p)
+ memmove(p, p+5, strlen(p+5)+1);
fmt = buf;
}
@@ -214,6 +228,8 @@ warnl(int line, char *fmt, ...)
va_start(arg, fmt);
adderr(line, fmt, arg);
va_end(arg);
+ if(debug['m'])
+ flusherrors();
}
void
@@ -377,6 +393,7 @@ importdot(Pkg *opkg, Node *pack)
Sym *s, *s1;
uint32 h;
int n;
+ char *pkgerror;
n = 0;
for(h=0; h<NHASH; h++) {
@@ -389,12 +406,14 @@ importdot(Pkg *opkg, Node *pack)
continue;
s1 = lookup(s->name);
if(s1->def != N) {
- redeclare(s1, "during import");
+ pkgerror = smprint("during import \"%Z\"", opkg->path);
+ redeclare(s1, pkgerror);
continue;
}
s1->def = s->def;
s1->block = s->block;
s1->def->pack = pack;
+ s1->origpkg = opkg;
n++;
}
}
@@ -494,6 +513,31 @@ nod(int op, Node *nleft, Node *nright)
return n;
}
+void
+saveorignode(Node *n)
+{
+ Node *norig;
+
+ if(n->orig != N)
+ return;
+ norig = nod(n->op, N, N);
+ *norig = *n;
+ n->orig = norig;
+}
+
+// ispaddedfield returns whether the given field
+// is followed by padding. For the case where t is
+// the last field, total gives the size of the enclosing struct.
+static int
+ispaddedfield(Type *t, vlong total)
+{
+ if(t->etype != TFIELD)
+ fatal("ispaddedfield called non-field %T", t);
+ if(t->down == T)
+ return t->width + t->type->width != total;
+ return t->width + t->type->width != t->down->width;
+}
+
int
algtype1(Type *t, Type **bad)
{
@@ -571,8 +615,12 @@ algtype1(Type *t, Type **bad)
}
ret = AMEM;
for(t1=t->type; t1!=T; t1=t1->down) {
- if(isblanksym(t1->sym))
+ // Blank fields and padding must be ignored,
+ // so need special compare.
+ if(isblanksym(t1->sym) || ispaddedfield(t1, t->width)) {
+ ret = -1;
continue;
+ }
a = algtype1(t1->type, bad);
if(a == ANOEQ)
return ANOEQ; // not comparable
@@ -813,6 +861,7 @@ treecopy(Node *n)
default:
m = nod(OXXX, N, N);
*m = *n;
+ m->orig = m;
m->left = treecopy(n->left);
m->right = treecopy(n->right);
m->list = listtreecopy(n->list);
@@ -1214,7 +1263,7 @@ assignop(Type *src, Type *dst, char **why)
return 0;
}
if(src->etype == TINTER && dst->etype != TBLANK) {
- if(why != nil)
+ if(why != nil && implements(dst, src, &missing, &have, &ptr))
*why = ": need type assertion";
return 0;
}
@@ -1379,6 +1428,7 @@ assignconv(Node *n, Type *t, char *context)
r->type = t;
r->typecheck = 1;
r->implicit = 1;
+ r->orig = n->orig;
return r;
}
@@ -2029,11 +2079,13 @@ cheapexpr(Node *n, NodeList **init)
/*
* return n in a local variable of type t if it is not already.
+ * the value is guaranteed not to change except by direct
+ * assignment to it.
*/
Node*
localexpr(Node *n, Type *t, NodeList **init)
{
- if(n->op == ONAME &&
+ if(n->op == ONAME && !n->addrtaken &&
(n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) &&
convertop(n->type, t, nil) == OCONVNOP)
return n;
@@ -2508,6 +2560,9 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
funcbody(fn);
curfn = fn;
+ // wrappers where T is anonymous (struct{ NamedType }) can be duplicated.
+ if(rcvr->etype == TSTRUCT || isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT)
+ fn->dupok = 1;
typecheck(&fn, Etop);
typechecklist(fn->nbody, Etop);
curfn = nil;
@@ -2591,7 +2646,7 @@ genhash(Sym *sym, Type *t)
Node *hashel;
Type *first, *t1;
int old_safemode;
- int64 size, mul;
+ int64 size, mul, offend;
if(debug['r'])
print("genhash %S %T\n", sym, t);
@@ -2664,7 +2719,7 @@ genhash(Sym *sym, Type *t)
call->list = list(call->list, nh);
call->list = list(call->list, nodintconst(t->type->width));
nx = nod(OINDEX, np, ni);
- nx->etype = 1; // no bounds check
+ nx->bounded = 1;
na = nod(OADDR, nx, N);
na->etype = 1; // no escape to heap
call->list = list(call->list, na);
@@ -2677,22 +2732,21 @@ genhash(Sym *sym, Type *t)
// Walk the struct using memhash for runs of AMEM
// and calling specific hash functions for the others.
first = T;
+ offend = 0;
for(t1=t->type;; t1=t1->down) {
- if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) {
- if(first == T && !isblanksym(t1->sym))
+ if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) {
+ offend = t1->width + t1->type->width;
+ if(first == T)
first = t1;
- continue;
+ // If it's a memory field but it's padded, stop here.
+ if(ispaddedfield(t1, t->width))
+ t1 = t1->down;
+ else
+ continue;
}
// Run memhash for fields up to this one.
- while(first != T && isblanksym(first->sym))
- first = first->down;
if(first != T) {
- if(first->down == t1)
- size = first->type->width;
- else if(t1 == T)
- size = t->width - first->width; // first->width is offset
- else
- size = t1->width - first->width; // both are offsets
+ size = offend - first->width; // first->width is offset
hashel = hashmem(first->type);
// hashel(h, size, &p.first)
call = nod(OCALL, hashel, N);
@@ -2708,6 +2762,8 @@ genhash(Sym *sym, Type *t)
}
if(t1 == T)
break;
+ if(isblanksym(t1->sym))
+ continue;
// Run hash for this field.
hashel = hashfor(t1->type);
@@ -2721,6 +2777,8 @@ genhash(Sym *sym, Type *t)
call->list = list(call->list, na);
fn->nbody = list(fn->nbody, call);
}
+ // make sure body is not empty.
+ fn->nbody = list(fn->nbody, nod(ORETURN, N, N));
break;
}
@@ -2822,6 +2880,7 @@ geneq(Sym *sym, Type *t)
Type *t1, *first;
int old_safemode;
int64 size;
+ int64 offend;
if(debug['r'])
print("geneq %S %T\n", sym, t);
@@ -2875,9 +2934,9 @@ geneq(Sym *sym, Type *t)
// if p[i] != q[i] { *eq = false; return }
nx = nod(OINDEX, np, ni);
- nx->etype = 1; // no bounds check
+ nx->bounded = 1;
ny = nod(OINDEX, nq, ni);
- ny->etype = 1; // no bounds check
+ ny->bounded = 1;
nif = nod(OIF, N, N);
nif->ntest = nod(ONE, nx, ny);
@@ -2893,18 +2952,23 @@ geneq(Sym *sym, Type *t)
case TSTRUCT:
// Walk the struct using memequal for runs of AMEM
// and calling specific equality tests for the others.
+ // Skip blank-named fields.
first = T;
+ offend = 0;
for(t1=t->type;; t1=t1->down) {
- if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) {
- if(first == T && !isblanksym(t1->sym))
+ if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) {
+ offend = t1->width + t1->type->width;
+ if(first == T)
first = t1;
- continue;
+ // If it's a memory field but it's padded, stop here.
+ if(ispaddedfield(t1, t->width))
+ t1 = t1->down;
+ else
+ continue;
}
// Run memequal for fields up to this one.
// TODO(rsc): All the calls to newname are wrong for
// cross-package unexported fields.
- while(first != T && isblanksym(first->sym))
- first = first->down;
if(first != T) {
if(first->down == t1) {
fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
@@ -2915,16 +2979,15 @@ geneq(Sym *sym, Type *t)
fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
} else {
// More than two fields: use memequal.
- if(t1 == T)
- size = t->width - first->width; // first->width is offset
- else
- size = t1->width - first->width; // both are offsets
+ size = offend - first->width; // first->width is offset
fn->nbody = list(fn->nbody, eqmem(np, nq, newname(first->sym), size, neq));
}
first = T;
}
if(t1 == T)
break;
+ if(isblanksym(t1->sym))
+ continue;
// Check this field, which is not just memory.
fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->sym), neq));
@@ -3031,7 +3094,7 @@ implements(Type *t, Type *iface, Type **m, Type **samename, int *ptr)
for(im=iface->type; im; im=im->down) {
imtype = methodfunc(im->type, 0);
tm = ifacelookdot(im->sym, t, &followptr, 0);
- if(tm == T || !eqtype(methodfunc(tm->type, 0), imtype)) {
+ if(tm == T || tm->nointerface || !eqtype(methodfunc(tm->type, 0), imtype)) {
if(tm == T)
tm = ifacelookdot(im->sym, t, &followptr, 1);
*m = im;
@@ -3504,11 +3567,8 @@ umagic(Magic *m)
Sym*
ngotype(Node *n)
{
- if(n->sym != S && n->realtype != T)
- if(strncmp(n->sym->name, "autotmp_", 8) != 0)
- if(strncmp(n->sym->name, "statictmp_", 8) != 0)
- return typename(n->realtype)->left->sym;
-
+ if(n->type != T)
+ return typenamesym(n->type);
return S;
}
@@ -3564,9 +3624,6 @@ mkpkg(Strlit *path)
Pkg *p;
int h;
- if(isbadimport(path))
- errorexit();
-
h = stringhash(path->s) & (nelem(phash)-1);
for(p=phash[h]; p; p=p->link)
if(p->path->len == path->len && memcmp(path->s, p->path->s, path->len) == 0)
@@ -3615,9 +3672,15 @@ addinit(Node **np, NodeList *init)
n->ullman = UINF;
}
+static char* reservedimports[] = {
+ "go",
+ "type",
+};
+
int
isbadimport(Strlit *path)
{
+ int i;
char *s;
Rune r;
@@ -3625,6 +3688,13 @@ isbadimport(Strlit *path)
yyerror("import path contains NUL");
return 1;
}
+
+ for(i=0; i<nelem(reservedimports); i++) {
+ if(strcmp(path->s, reservedimports[i]) == 0) {
+ yyerror("import path \"%s\" is reserved and cannot be used", path->s);
+ return 1;
+ }
+ }
s = path->s;
while(*s) {
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index f1a95587f..a497b8622 100644
--- a/src/cmd/gc/swt.c
+++ b/src/cmd/gc/swt.c
@@ -117,12 +117,15 @@ exprcmp(Case *c1, Case *c2)
n1 = c1->node->left;
n2 = c2->node->left;
+ // sort by type (for switches on interface)
ct = n1->val.ctype;
- if(ct != n2->val.ctype) {
- // invalid program, but return a sort
- // order so that we can give a better
- // error later.
+ if(ct != n2->val.ctype)
return ct - n2->val.ctype;
+ if(!eqtype(n1->type, n2->type)) {
+ if(n1->type->vargen > n2->type->vargen)
+ return +1;
+ else
+ return -1;
}
// sort by constant value
@@ -259,10 +262,11 @@ casebody(Node *sw, Node *typeswvar)
Node *go, *br;
int32 lno, needvar;
- lno = setlineno(sw);
if(sw->list == nil)
return;
+ lno = setlineno(sw);
+
cas = nil; // cases
stat = nil; // statements
def = N; // defaults
@@ -270,7 +274,7 @@ casebody(Node *sw, Node *typeswvar)
for(l=sw->list; l; l=l->next) {
n = l->n;
- lno = setlineno(n);
+ setlineno(n);
if(n->op != OXCASE)
fatal("casebody %O", n->op);
n->op = OCASE;
@@ -378,6 +382,7 @@ mkcaselist(Node *sw, int arg)
case Strue:
case Sfalse:
c->type = Texprvar;
+ c->hash = typehash(n->left->type);
switch(consttype(n->left)) {
case CTFLT:
case CTINT:
@@ -442,6 +447,10 @@ exprbsw(Case *c0, int ncase, int arg)
n = c0->node;
lno = setlineno(n);
+ if(assignop(n->left->type, exprname->type, nil) == OCONVIFACE ||
+ assignop(exprname->type, n->left->type, nil) == OCONVIFACE)
+ goto snorm;
+
switch(arg) {
case Strue:
a = nod(OIF, N, N);
@@ -457,6 +466,7 @@ exprbsw(Case *c0, int ncase, int arg)
break;
default:
+ snorm:
a = nod(OIF, N, N);
a->ntest = nod(OEQ, exprname, n->left); // if name == val
typecheck(&a->ntest, Erv);
@@ -520,6 +530,8 @@ exprswitch(Node *sw)
exprname = temp(sw->ntest->type);
cas = list1(nod(OAS, exprname, sw->ntest));
typechecklist(cas, Etop);
+ } else {
+ exprname = nodbool(arg == Strue);
}
c0 = mkcaselist(sw, arg);
@@ -786,7 +798,6 @@ typeswitch(Node *sw)
void
walkswitch(Node *sw)
{
-
/*
* reorder the body into (OLIST, cases, statements)
* cases have OGOTO into statements.
@@ -813,7 +824,7 @@ typecheckswitch(Node *n)
{
int top, lno, ptr;
char *nilonly;
- Type *t, *missing, *have;
+ Type *t, *badtype, *missing, *have;
NodeList *l, *ll;
Node *ncase, *nvar;
Node *def;
@@ -839,10 +850,14 @@ typecheckswitch(Node *n)
} else
t = types[TBOOL];
if(t) {
- if(!okforeq[t->etype] || isfixedarray(t))
+ if(!okforeq[t->etype])
yyerror("cannot switch on %lN", n->ntest);
- else if(t->etype == TARRAY)
+ else if(t->etype == TARRAY && !isfixedarray(t))
nilonly = "slice";
+ else if(t->etype == TARRAY && isfixedarray(t) && algtype1(t, nil) == ANOEQ)
+ yyerror("cannot switch on %lN", n->ntest);
+ else if(t->etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ)
+ yyerror("cannot switch on %lN (struct containing %T cannot be compared)", n->ntest, badtype);
else if(t->etype == TFUNC)
nilonly = "func";
else if(t->etype == TMAP)
@@ -889,7 +904,7 @@ typecheckswitch(Node *n)
yyerror("%lN is not a type", ll->n);
// reset to original type
ll->n = n->ntest->right;
- } else if(ll->n->type->etype != TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) {
+ } else if(ll->n->type->etype != TINTER && t->etype == TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) {
if(have && !missing->broke && !have->broke)
yyerror("impossible type switch case: %lN cannot have dynamic type %T"
" (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT",
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index cc4faf5a7..fbab85d03 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -31,6 +31,8 @@ static void checkassign(Node*);
static void checkassignlist(NodeList*);
static void stringtoarraylit(Node**);
static Node* resolve(Node*);
+static void checkdefergo(Node*);
+static int checkmake(Type*, char*, Node*);
static NodeList* typecheckdefstack;
@@ -106,6 +108,27 @@ typekind(Type *t)
}
/*
+ * sprint_depchain prints a dependency chain
+ * of nodes into fmt.
+ * It is used by typecheck in the case of OLITERAL nodes
+ * to print constant definition loops.
+ */
+static void
+sprint_depchain(Fmt *fmt, NodeList *stack, Node *cur, Node *first)
+{
+ NodeList *l;
+
+ for(l = stack; l; l=l->next) {
+ if(l->n->op == cur->op) {
+ if(l->n != first)
+ sprint_depchain(fmt, l->next, l->n, first);
+ fmtprint(fmt, "\n\t%L: %N uses %N", l->n->lineno, l->n, cur);
+ return;
+ }
+ }
+}
+
+/*
* type check node *np.
* replaces *np with a new pointer in some cases.
* returns the final value of *np as a convenience.
@@ -155,6 +178,24 @@ typecheck(Node **np, int top)
}
if(n->typecheck == 2) {
+ // Typechecking loop. Trying printing a meaningful message,
+ // otherwise a stack trace of typechecking.
+ switch(n->op) {
+ case ONAME:
+ // We can already diagnose variables used as types.
+ if((top & (Erv|Etype)) == Etype)
+ yyerror("%N is not a type", n);
+ break;
+ case OLITERAL:
+ if((top & (Erv|Etype)) == Etype) {
+ yyerror("%N is not a type", n);
+ break;
+ }
+ fmtstrinit(&fmt);
+ sprint_depchain(&fmt, tcstack, n, n);
+ yyerrorl(n->lineno, "constant definition loop%s", fmtstrflush(&fmt));
+ break;
+ }
if(nsavederrors+nerrors == 0) {
fmtstrinit(&fmt);
for(l=tcstack; l; l=l->next)
@@ -165,7 +206,7 @@ typecheck(Node **np, int top)
return n;
}
n->typecheck = 2;
-
+
if(tcfree != nil) {
l = tcfree;
tcfree = l->next;
@@ -206,6 +247,12 @@ callrecv(Node *n)
case OCALLINTER:
case OCALLFUNC:
case ORECV:
+ case OCAP:
+ case OLEN:
+ case OCOPY:
+ case ONEW:
+ case OAPPEND:
+ case ODELETE:
return 1;
}
@@ -249,7 +296,6 @@ typecheck1(Node **np, int top)
}
typecheckdef(n);
- n->realtype = n->type;
if(n->op == ONONAME)
goto error;
}
@@ -331,8 +377,11 @@ reswitch:
t->bound = -1; // slice
} else if(l->op == ODDD) {
t->bound = -100; // to be filled in
- if(!(top&Ecomplit))
+ if(!(top&Ecomplit) && !n->diag) {
+ t->broke = 1;
+ n->diag = 1;
yyerror("use of [...] array outside of array literal");
+ }
} else {
l = typecheck(&n->left, Erv);
switch(consttype(l)) {
@@ -351,8 +400,10 @@ reswitch:
if(t->bound < 0) {
yyerror("array bound must be non-negative");
goto error;
- } else
- overflow(v, types[TINT]);
+ } else if(doesoverflow(v, types[TINT])) {
+ yyerror("array bound is too large");
+ goto error;
+ }
}
typecheck(&r, Etype);
if(r->type == T)
@@ -396,7 +447,7 @@ reswitch:
ok |= Etype;
n->op = OTYPE;
n->type = tostruct(n->list);
- if(n->type == T)
+ if(n->type == T || n->type->broke)
goto error;
n->list = nil;
break;
@@ -436,8 +487,11 @@ reswitch:
goto ret;
}
if(!isptr[t->etype]) {
- yyerror("invalid indirect of %lN", n->left);
- goto error;
+ if(top & (Erv | Etop)) {
+ yyerror("invalid indirect of %lN", n->left);
+ goto error;
+ }
+ goto ret;
}
ok |= Erv;
n->type = t->type;
@@ -567,7 +621,10 @@ reswitch:
n->left = l;
n->right = r;
}
- }
+ // non-comparison operators on ideal bools should make them lose their ideal-ness
+ } else if(t == idealbool)
+ t = types[TBOOL];
+
if(et == TSTRING) {
if(iscmp[n->op]) {
n->etype = n->op;
@@ -587,6 +644,13 @@ reswitch:
n->op = OCMPIFACE;
}
}
+
+ if((op == ODIV || op == OMOD) && isconst(r, CTINT))
+ if(mpcmpfixc(r->val.u.xval, 0) == 0) {
+ yyerror("division by zero");
+ goto error;
+ }
+
n->type = t;
goto ret;
@@ -697,6 +761,10 @@ reswitch:
n->op = ODOTPTR;
checkwidth(t);
}
+ if(isblank(n->right)) {
+ yyerror("cannot refer to blank field or method");
+ goto error;
+ }
if(!lookdot(n, t, 0)) {
if(lookdot(n, t, 1))
yyerror("%N undefined (cannot refer to unexported field or method %S)", n, n->right->sym);
@@ -735,14 +803,20 @@ reswitch:
}
if(n->type != T && n->type->etype != TINTER)
if(!implements(n->type, t, &missing, &have, &ptr)) {
- if(have)
- yyerror("impossible type assertion: %lN cannot have dynamic type %T"
- " (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT",
- l, n->type, missing->sym, have->sym, have->type,
- missing->sym, missing->type);
+ if(have && have->sym == missing->sym)
+ yyerror("impossible type assertion:\n\t%T does not implement %T (wrong type for %S method)\n"
+ "\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
+ have->sym, have->type, missing->sym, missing->type);
+ else if(ptr)
+ yyerror("impossible type assertion:\n\t%T does not implement %T (%S method requires pointer receiver)",
+ n->type, t, missing->sym);
+ else if(have)
+ yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)\n"
+ "\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
+ have->sym, have->type, missing->sym, missing->type);
else
- yyerror("impossible type assertion: %lN cannot have dynamic type %T"
- " (missing %S method)", l, n->type, missing->sym);
+ yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)",
+ n->type, t, missing->sym);
goto error;
}
goto ret;
@@ -762,11 +836,35 @@ reswitch:
yyerror("invalid operation: %N (index of type %T)", n, t);
goto error;
+
+ case TSTRING:
case TARRAY:
defaultlit(&n->right, T);
- if(n->right->type != T && !isint[n->right->type->etype])
- yyerror("non-integer array index %N", n->right);
- n->type = t->type;
+ if(t->etype == TSTRING)
+ n->type = types[TUINT8];
+ else
+ n->type = t->type;
+ why = "string";
+ if(t->etype == TARRAY) {
+ if(isfixedarray(t))
+ why = "array";
+ else
+ why = "slice";
+ }
+ if(n->right->type != T && !isint[n->right->type->etype]) {
+ yyerror("non-integer %s index %N", why, n->right);
+ break;
+ }
+ if(n->right->op == OLITERAL) {
+ 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);
+ else if(isconst(n->left, CTSTR) && mpgetfix(n->right->val.u.xval) >= n->left->val.u.sval->len)
+ yyerror("invalid string index %N (out of bounds for %d-byte string)", n->right, n->left->val.u.sval->len);
+ else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
+ yyerror("invalid %s index %N (index too large)", why, n->right);
+ }
break;
case TMAP:
@@ -777,13 +875,6 @@ reswitch:
n->type = t->type;
n->op = OINDEXMAP;
break;
-
- case TSTRING:
- defaultlit(&n->right, types[TUINT]);
- if(n->right->type != T && !isint[n->right->type->etype])
- yyerror("non-integer string index %N", n->right);
- n->type = types[TUINT8];
- break;
}
goto ret;
@@ -843,7 +934,8 @@ reswitch:
defaultlit(&n->left, T);
defaultlit(&n->right->left, T);
defaultlit(&n->right->right, T);
- if(isfixedarray(n->left->type)) {
+ l = n->left;
+ if(isfixedarray(l->type)) {
if(!islvalue(n->left)) {
yyerror("invalid operation %N (slice of unaddressable value)", n);
goto error;
@@ -851,6 +943,26 @@ reswitch:
n->left = nod(OADDR, n->left, N);
n->left->implicit = 1;
typecheck(&n->left, Erv);
+ l = n->left;
+ }
+ if((t = l->type) == T)
+ goto error;
+ tp = nil;
+ if(istype(t, TSTRING)) {
+ n->type = t;
+ n->op = OSLICESTR;
+ } else if(isptr[t->etype] && isfixedarray(t->type)) {
+ tp = t->type;
+ n->type = typ(TARRAY);
+ n->type->type = tp->type;
+ n->type->bound = -1;
+ dowidth(n->type);
+ n->op = OSLICEARR;
+ } else if(isslice(t)) {
+ n->type = t;
+ } else {
+ yyerror("cannot slice %N (type %T)", l, t);
+ goto error;
}
if(n->right->left != N) {
if((t = n->right->left->type) == T)
@@ -859,6 +971,18 @@ reswitch:
yyerror("invalid slice index %N (type %T)", n->right->left, t);
goto error;
}
+ if(n->right->left->op == OLITERAL) {
+ if(mpgetfix(n->right->left->val.u.xval) < 0) {
+ yyerror("invalid slice index %N (index must be non-negative)", n->right->left);
+ goto error;
+ } else if(tp != nil && tp->bound > 0 && mpgetfix(n->right->left->val.u.xval) > tp->bound) {
+ yyerror("invalid slice index %N (out of bounds for %d-element array)", n->right->left, tp->bound);
+ goto error;
+ } else if(mpcmpfixfix(n->right->left->val.u.xval, maxintval[TINT]) > 0) {
+ yyerror("invalid slice index %N (index too large)", n->right->left);
+ goto error;
+ }
+ }
}
if(n->right->right != N) {
if((t = n->right->right->type) == T)
@@ -867,29 +991,28 @@ reswitch:
yyerror("invalid slice index %N (type %T)", n->right->right, t);
goto error;
}
+ if(n->right->right->op == OLITERAL) {
+ if(mpgetfix(n->right->right->val.u.xval) < 0) {
+ yyerror("invalid slice index %N (index must be non-negative)", n->right->right);
+ goto error;
+ } else if(tp != nil && tp->bound > 0 && mpgetfix(n->right->right->val.u.xval) > tp->bound) {
+ yyerror("invalid slice index %N (out of bounds for %d-element array)", n->right->right, tp->bound);
+ goto error;
+ } else if(mpcmpfixfix(n->right->right->val.u.xval, maxintval[TINT]) > 0) {
+ yyerror("invalid slice index %N (index too large)", n->right->right);
+ goto error;
+ }
+ }
}
- l = n->left;
- if((t = l->type) == T)
+ if(n->right->left != N
+ && n->right->right != N
+ && n->right->left->op == OLITERAL
+ && n->right->right->op == OLITERAL
+ && mpcmpfixfix(n->right->left->val.u.xval, n->right->right->val.u.xval) > 0) {
+ yyerror("inverted slice index %N > %N", n->right->left, n->right->right);
goto error;
- if(istype(t, TSTRING)) {
- n->type = t;
- n->op = OSLICESTR;
- goto ret;
- }
- if(isptr[t->etype] && isfixedarray(t->type)) {
- n->type = typ(TARRAY);
- n->type->type = t->type->type;
- n->type->bound = -1;
- dowidth(n->type);
- n->op = OSLICEARR;
- goto ret;
- }
- if(isslice(t)) {
- n->type = t;
- goto ret;
}
- yyerror("cannot slice %N (type %T)", l, t);
- goto error;
+ goto ret;
/*
* call and call like
@@ -916,8 +1039,11 @@ reswitch:
defaultlit(&n->left, T);
l = n->left;
if(l->op == OTYPE) {
- if(n->isddd || l->type->bound == -100)
- yyerror("invalid use of ... in type conversion", l);
+ if(n->isddd || l->type->bound == -100) {
+ if(!l->type->broke)
+ yyerror("invalid use of ... in type conversion", l);
+ n->diag = 1;
+ }
// pick off before type-checking arguments
ok |= Erv;
// turn CALL(type, arg) into CONV(arg) w/ type
@@ -929,7 +1055,7 @@ reswitch:
goto doconv;
}
- if(count(n->list) == 1)
+ if(count(n->list) == 1 && !n->isddd)
typecheck(&n->list->n, Erv | Efnstruct);
else
typechecklist(n->list, Erv);
@@ -1011,10 +1137,12 @@ reswitch:
if(!iscomplex[t->etype])
goto badcall1;
if(isconst(l, CTCPLX)){
+ r = n;
if(n->op == OREAL)
n = nodfltconst(&l->val.u.cval->real);
else
n = nodfltconst(&l->val.u.cval->imag);
+ n->orig = r;
}
n->type = types[cplxsubtype(t->etype)];
goto ret;
@@ -1074,7 +1202,9 @@ reswitch:
}
if(l->op == OLITERAL && r->op == OLITERAL) {
// make it a complex literal
- n = nodcplxlit(l->val, r->val);
+ r = nodcplxlit(l->val, r->val);
+ r->orig = n;
+ n = r;
}
n->type = t;
goto ret;
@@ -1214,17 +1344,25 @@ reswitch:
case OCONV:
doconv:
ok |= Erv;
+ saveorignode(n);
typecheck(&n->left, Erv | (top & (Eindir | Eiota)));
convlit1(&n->left, n->type, 1);
if((t = n->left->type) == T || n->type == T)
goto error;
if((n->op = convertop(t, n->type, &why)) == 0) {
- yyerror("cannot convert %lN to type %T%s", n->left, n->type, why);
+ if(!n->diag && !n->type->broke) {
+ yyerror("cannot convert %lN to type %T%s", n->left, n->type, why);
+ n->diag = 1;
+ }
n->op = OCONV;
}
switch(n->op) {
case OCONVNOP:
if(n->left->op == OLITERAL) {
+ r = nod(OXXX, N, N);
+ n->op = OCONV;
+ n->orig = r;
+ *r = *n;
n->op = OLITERAL;
n->val = n->left->val;
}
@@ -1267,22 +1405,20 @@ reswitch:
l = args->n;
args = args->next;
typecheck(&l, Erv);
- defaultlit(&l, types[TINT]);
r = N;
if(args != nil) {
r = args->n;
args = args->next;
typecheck(&r, Erv);
- defaultlit(&r, types[TINT]);
}
if(l->type == T || (r && r->type == T))
goto error;
- if(!isint[l->type->etype]) {
- yyerror("non-integer len argument to make(%T)", t);
+ et = checkmake(t, "len", l) < 0;
+ et |= r && checkmake(t, "cap", r) < 0;
+ if(et)
goto error;
- }
- if(r && !isint[r->type->etype]) {
- yyerror("non-integer cap argument to make(%T)", t);
+ if(isconst(l, CTINT) && r && isconst(r, CTINT) && mpcmpfixfix(l->val.u.xval, r->val.u.xval) > 0) {
+ yyerror("len larger than cap in make(%T)", t);
goto error;
}
n->left = l;
@@ -1298,10 +1434,8 @@ reswitch:
defaultlit(&l, types[TINT]);
if(l->type == T)
goto error;
- if(!isint[l->type->etype]) {
- yyerror("non-integer size argument to make(%T)", t);
+ if(checkmake(t, "size", l) < 0)
goto error;
- }
n->left = l;
} else
n->left = nodintconst(0);
@@ -1317,10 +1451,8 @@ reswitch:
defaultlit(&l, types[TINT]);
if(l->type == T)
goto error;
- if(!isint[l->type->etype]) {
- yyerror("non-integer buffer argument to make(%T)", t);
+ if(checkmake(t, "buffer", l) < 0)
goto error;
- }
n->left = l;
} else
n->left = nodintconst(0);
@@ -1402,6 +1534,21 @@ reswitch:
fatal("OITAB of %T", t);
n->type = ptrto(types[TUINTPTR]);
goto ret;
+
+ case OCLOSUREVAR:
+ ok |= Erv;
+ goto ret;
+
+ case OCFUNC:
+ ok |= Erv;
+ typecheck(&n->left, Erv);
+ n->type = types[TUINTPTR];
+ goto ret;
+
+ case OCONVNOP:
+ ok |= Erv;
+ typecheck(&n->left, Erv);
+ goto ret;
/*
* statements
@@ -1428,12 +1575,15 @@ reswitch:
case ODEFER:
ok |= Etop;
- typecheck(&n->left, Etop);
+ typecheck(&n->left, Etop|Erv);
+ if(!n->left->diag)
+ checkdefergo(n);
goto ret;
case OPROC:
ok |= Etop;
- typecheck(&n->left, Etop|Eproc);
+ typecheck(&n->left, Etop|Eproc|Erv);
+ checkdefergo(n);
goto ret;
case OFOR:
@@ -1530,9 +1680,7 @@ ret:
}
}
- // TODO(rsc): should not need to check importpkg,
- // but reflect mentions unsafe.Pointer.
- if(safemode && !incannedimport && !importpkg && t && t->etype == TUNSAFEPTR)
+ if(safemode && !incannedimport && !importpkg && !compiling_wrappers && t && t->etype == TUNSAFEPTR)
yyerror("cannot use unsafe.Pointer");
evconst(n);
@@ -1555,7 +1703,7 @@ ret:
}
if((top & Etop) && !(top & (Ecall|Erv|Etype)) && !(ok & Etop)) {
if(n->diag == 0) {
- yyerror("%N not used", n);
+ yyerror("%N evaluated but not used", n);
n->diag = 1;
}
goto error;
@@ -1579,6 +1727,56 @@ out:
}
static void
+checkdefergo(Node *n)
+{
+ char *what;
+
+ what = "defer";
+ if(n->op == OPROC)
+ what = "go";
+
+ switch(n->left->op) {
+ case OCALLINTER:
+ case OCALLMETH:
+ case OCALLFUNC:
+ case OCLOSE:
+ case OCOPY:
+ case ODELETE:
+ case OPANIC:
+ case OPRINT:
+ case OPRINTN:
+ case ORECOVER:
+ // ok
+ break;
+ case OAPPEND:
+ case OCAP:
+ case OCOMPLEX:
+ case OIMAG:
+ case OLEN:
+ case OMAKE:
+ case OMAKESLICE:
+ case OMAKECHAN:
+ case OMAKEMAP:
+ case ONEW:
+ case OREAL:
+ case OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
+ if(n->left->orig != N && n->left->orig->op == OCONV)
+ goto conv;
+ yyerror("%s discards result of %N", what, n->left);
+ break;
+ default:
+ conv:
+ if(!n->diag) {
+ // The syntax made sure it was a call, so this must be
+ // a conversion.
+ n->diag = 1;
+ yyerror("%s requires function call, not conversion", what);
+ }
+ break;
+ }
+}
+
+static void
implicitstar(Node **nn)
{
Type *t;
@@ -1682,7 +1880,7 @@ lookdot1(Node *errnode, Sym *s, Type *t, Type *f, int dostrcmp)
static int
looktypedot(Node *n, Type *t, int dostrcmp)
{
- Type *f1, *f2, *tt;
+ Type *f1, *f2;
Sym *s;
s = n->right->sym;
@@ -1692,8 +1890,6 @@ looktypedot(Node *n, Type *t, int dostrcmp)
if(f1 == T)
return 0;
- if(f1->width == BADWIDTH)
- fatal("lookdot badwidth %T %p", f1, f1);
n->right = methodname(n->right, t);
n->xoffset = f1->width;
n->type = f1->type;
@@ -1701,11 +1897,9 @@ looktypedot(Node *n, Type *t, int dostrcmp)
return 1;
}
- tt = t;
- if(t->sym == S && isptr[t->etype])
- tt = t->type;
-
- f2 = methtype(tt, 0);
+ // Find the base type: methtype will fail if t
+ // is not of the form T or *T.
+ f2 = methtype(t, 0);
if(f2 == T)
return 0;
@@ -1769,6 +1963,7 @@ lookdot(Node *n, Type *t, int dostrcmp)
fatal("lookdot badwidth %T %p", f1, f1);
n->xoffset = f1->width;
n->type = f1->type;
+ n->paramfld = f1;
if(t->etype == TINTER) {
if(isptr[n->left->type->etype]) {
n->left = nod(OIND, n->left, N); // implicitstar
@@ -2129,10 +2324,10 @@ static void
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;
+ Sym *s, *s1;
int32 lno;
ulong nhash;
Node *autohash[101];
@@ -2146,14 +2341,18 @@ typecheckcomplit(Node **np)
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.
@@ -2161,13 +2360,12 @@ typecheckcomplit(Node **np)
yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
goto error;
}
-
// Also, the underlying type must be a struct, map, slice, or array.
if(!iscomptype(t)) {
yyerror("invalid pointer type %T for composite literal", t);
goto error;
}
- t = t->type;
+ t = t->type;
}
switch(t->etype) {
@@ -2298,9 +2496,11 @@ typecheckcomplit(Node **np)
// Sym might have resolved to name in other top-level
// package, because of import dot. Redirect to correct sym
// before we do the lookup.
- if(s->pkg != localpkg && exportname(s->name))
- s = lookup(s->name);
-
+ if(s->pkg != localpkg && exportname(s->name)) {
+ s1 = lookup(s->name);
+ if(s1->origpkg == s->pkg)
+ s = s1;
+ }
f = lookdot1(nil, s, t, t->type, 0);
if(f == nil) {
yyerror("unknown %T field '%S' in struct literal", t, s);
@@ -2323,6 +2523,7 @@ typecheckcomplit(Node **np)
if(nerr != nerrors)
goto error;
+ n->orig = norig;
if(isptr[n->type->etype]) {
n = nod(OPTRLIT, n, N);
n->typecheck = 1;
@@ -2331,6 +2532,7 @@ typecheckcomplit(Node **np)
n->left->typecheck = 1;
}
+ n->orig = norig;
*np = n;
lineno = lno;
return;
@@ -2527,7 +2729,6 @@ typecheckas2(Node *n)
goto common;
case ORECV:
n->op = OAS2RECV;
- n->right = n->rlist->n;
goto common;
case ODOTTYPE:
n->op = OAS2DOTTYPE;
@@ -2572,7 +2773,7 @@ typecheckfunc(Node *n)
t->nname = n->nname;
rcvr = getthisx(t)->type;
if(rcvr != nil && n->shortname != N && !isblank(n->shortname))
- addmethod(n->shortname->sym, t, 1);
+ addmethod(n->shortname->sym, t, 1, n->nname->nointerface);
}
static void
@@ -2715,6 +2916,7 @@ typecheckdeftype(Node *n)
typecheck(&n->ntype, Etype);
if((t = n->ntype->type) == T) {
n->diag = 1;
+ n->type = T;
goto ret;
}
if(n->type == T) {
@@ -2828,14 +3030,14 @@ typecheckdef(Node *n)
yyerror("xxx");
}
typecheck(&e, Erv | Eiota);
- if(e->type != T && e->op != OLITERAL) {
- yyerror("const initializer must be constant");
- goto ret;
- }
if(isconst(e, CTNIL)) {
yyerror("const initializer cannot be nil");
goto ret;
}
+ if(e->type != T && e->op != OLITERAL || !isgoconst(e)) {
+ yyerror("const initializer %N is not a constant", e);
+ goto ret;
+ }
t = n->type;
if(t != T) {
if(!okforconst[t->etype]) {
@@ -2912,3 +3114,33 @@ ret:
n->walkdef = 1;
return n;
}
+
+static int
+checkmake(Type *t, char *arg, Node *n)
+{
+ if(n->op == OLITERAL) {
+ n->val = toint(n->val);
+ if(mpcmpfixc(n->val.u.xval, 0) < 0) {
+ yyerror("negative %s argument in make(%T)", arg, t);
+ return -1;
+ }
+ if(mpcmpfixfix(n->val.u.xval, maxintval[TINT]) > 0) {
+ yyerror("%s argument too large in make(%T)", arg, t);
+ return -1;
+ }
+
+ // Delay defaultlit until after we've checked range, to avoid
+ // a redundant "constant NNN overflows int" error.
+ defaultlit(&n, types[TINT]);
+ return 0;
+ }
+
+ // Defaultlit still necessary for non-constant: n might be 1<<k.
+ defaultlit(&n, types[TINT]);
+
+ if(!isint[n->type->etype]) {
+ yyerror("non-integer %s argument in make(%T) - %T", arg, t, n->type);
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index a4edc9062..de2105ed3 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -21,7 +21,13 @@ static NodeList* reorder3(NodeList*);
static Node* addstr(Node*, NodeList**);
static Node* appendslice(Node*, NodeList**);
static Node* append(Node*, NodeList**);
+static Node* sliceany(Node*, NodeList**);
static void walkcompare(Node**, NodeList**);
+static void walkrotate(Node**);
+static void walkmul(Node**, NodeList**);
+static void walkdiv(Node**, NodeList**);
+static int bounded(Node*, int64);
+static Mpint mpzero;
// can this code branch reach the end
// without an unconditional RETURN
@@ -178,8 +184,8 @@ walkstmt(Node **np)
dump("nottop", n);
break;
- case OASOP:
case OAS:
+ case OASOP:
case OAS2:
case OAS2DOTTYPE:
case OAS2RECV:
@@ -368,9 +374,10 @@ walkexpr(Node **np, NodeList **init)
NodeList *ll, *lr, *lpost;
Type *t;
int et;
- int64 v, v1, v2, len;
+ int64 v;
int32 lno;
- Node *n, *fn;
+ Node *n, *fn, *n1, *n2;
+ Sym *sym;
char buf[100], *p;
n = *np;
@@ -409,7 +416,7 @@ walkexpr(Node **np, NodeList **init)
switch(n->op) {
default:
dump("walk", n);
- fatal("walkexpr: switch 1 unknown op %N", n);
+ fatal("walkexpr: switch 1 unknown op %+hN", n);
break;
case OTYPE:
@@ -424,14 +431,23 @@ walkexpr(Node **np, NodeList **init)
case OCOM:
case OREAL:
case OIMAG:
- case ODOT:
- case ODOTPTR:
case ODOTMETH:
case ODOTINTER:
case OIND:
walkexpr(&n->left, init);
goto ret;
+ case ODOT:
+ case ODOTPTR:
+ usefield(n);
+ walkexpr(&n->left, init);
+ goto ret;
+
+ case OEFACE:
+ walkexpr(&n->left, init);
+ walkexpr(&n->right, init);
+ goto ret;
+
case OITAB:
walkexpr(&n->left, init);
goto ret;
@@ -454,19 +470,34 @@ walkexpr(Node **np, NodeList **init)
case OLSH:
case ORSH:
+ walkexpr(&n->left, init);
+ walkexpr(&n->right, init);
+ shiftwalked:
+ t = n->left->type;
+ n->bounded = bounded(n->right, 8*t->width);
+ if(debug['m'] && n->etype && !isconst(n->right, CTINT))
+ warn("shift bounds check elided");
+ goto ret;
+
case OAND:
- case OOR:
- case OXOR:
case OSUB:
- case OMUL:
+ case OHMUL:
case OLT:
case OLE:
case OGE:
case OGT:
case OADD:
case OCOMPLEX:
+ case OLROT:
+ walkexpr(&n->left, init);
+ walkexpr(&n->right, init);
+ goto ret;
+
+ case OOR:
+ case OXOR:
walkexpr(&n->left, init);
walkexpr(&n->right, init);
+ walkrotate(&n);
goto ret;
case OEQ:
@@ -505,6 +536,11 @@ walkexpr(Node **np, NodeList **init)
n->addable = 1;
goto ret;
+ case OCLOSUREVAR:
+ case OCFUNC:
+ n->addable = 1;
+ goto ret;
+
case ONAME:
if(!(n->class & PHEAP) && n->class != PPARAMREF)
n->addable = 1;
@@ -525,10 +561,12 @@ 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);
@@ -656,6 +694,31 @@ walkexpr(Node **np, NodeList **init)
n->ninit = nil;
r = n->rlist->n;
walkexprlistsafe(n->list, init);
+ if(isblank(n->list->n) && !isinter(r->type)) {
+ strcpy(buf, "assert");
+ p = buf+strlen(buf);
+ if(isnilinter(r->left->type))
+ *p++ = 'E';
+ else
+ *p++ = 'I';
+ *p++ = '2';
+ *p++ = 'T';
+ *p++ = 'O';
+ *p++ = 'K';
+ *p = '\0';
+
+ fn = syslook(buf, 1);
+ ll = list1(typename(r->type));
+ ll = list(ll, r->left);
+ argtype(fn, r->left->type);
+ n1 = nod(OCALL, fn, N);
+ n1->list = ll;
+ n = nod(OAS, n->list->next->n, n1);
+ typecheck(&n, Etop);
+ walkexpr(&n, init);
+ goto ret;
+ }
+
r->op = ODOTTYPE2;
walkexpr(&r, init);
ll = ascompatet(n->op, n->list, &r->type, 0, init);
@@ -694,10 +757,22 @@ walkexpr(Node **np, NodeList **init)
goto ret;
case OCONVIFACE:
+ walkexpr(&n->left, init);
+
+ // Optimize convT2E as a two-word copy when T is uintptr-shaped.
+ if(!isinter(n->left->type) && isnilinter(n->type) &&
+ (n->left->type->width == widthptr) &&
+ isint[simsimtype(n->left->type)]) {
+ l = nod(OEFACE, typename(n->left->type), n->left);
+ l->type = n->type;
+ l->typecheck = n->typecheck;
+ n = l;
+ goto ret;
+ }
+
// Build name of function: convI2E etc.
// Not all names are possible
// (e.g., we'll never generate convE2E or convE2I).
- walkexpr(&n->left, init);
strcpy(buf, "conv");
p = buf+strlen(buf);
if(isnilinter(n->left->type))
@@ -719,6 +794,60 @@ walkexpr(Node **np, NodeList **init)
ll = list(ll, typename(n->left->type));
if(!isnilinter(n->type))
ll = list(ll, typename(n->type));
+ if(!isinter(n->left->type) && !isnilinter(n->type)){
+ sym = pkglookup(smprint("%-T.%-T", n->left->type, n->type), itabpkg);
+ if(sym->def == N) {
+ l = nod(ONAME, N, N);
+ l->sym = sym;
+ l->type = ptrto(types[TUINT8]);
+ l->addable = 1;
+ l->class = PEXTERN;
+ l->xoffset = 0;
+ sym->def = l;
+ ggloblsym(sym, widthptr, 1, 0);
+ }
+ l = nod(OADDR, sym->def, N);
+ l->addable = 1;
+ ll = list(ll, l);
+
+ if(n->left->type->width == widthptr &&
+ isint[simsimtype(n->left->type)]) {
+ /* For pointer types, we can make a special form of optimization
+ *
+ * These statements are put onto the expression init list:
+ * Itab *tab = atomicloadtype(&cache);
+ * if(tab == nil)
+ * tab = typ2Itab(type, itype, &cache);
+ *
+ * The CONVIFACE expression is replaced with this:
+ * OEFACE{tab, ptr};
+ */
+ l = temp(ptrto(types[TUINT8]));
+
+ n1 = nod(OAS, l, sym->def);
+ typecheck(&n1, Etop);
+ *init = list(*init, n1);
+
+ fn = syslook("typ2Itab", 1);
+ n1 = nod(OCALL, fn, N);
+ n1->list = ll;
+ typecheck(&n1, Erv);
+ walkexpr(&n1, init);
+
+ n2 = nod(OIF, N, N);
+ n2->ntest = nod(OEQ, l, nodnil());
+ n2->nbody = list1(nod(OAS, l, n1));
+ n2->likely = -1;
+ typecheck(&n2, Etop);
+ *init = list(*init, n2);
+
+ l = nod(OEFACE, l, n->left);
+ l->typecheck = n->typecheck;
+ l->type = n->type;
+ n = l;
+ goto ret;
+ }
+ }
ll = list(ll, n->left);
argtype(fn, n->left->type);
argtype(fn, n->type);
@@ -772,7 +901,7 @@ walkexpr(Node **np, NodeList **init)
* on 386, rewrite float ops into l = l op r.
* everywhere, rewrite map ops into l = l op r.
* everywhere, rewrite string += into l = l op r.
- * everywhere, rewrite complex /= into l = l op r.
+ * everywhere, rewrite integer/complex /= into l = l op r.
* TODO(rsc): Maybe this rewrite should be done always?
*/
et = n->left->type->etype;
@@ -780,7 +909,8 @@ walkexpr(Node **np, NodeList **init)
(thechar == '8' && isfloat[et]) ||
l->op == OINDEXMAP ||
et == TSTRING ||
- (iscomplex[et] && n->etype == ODIV)) {
+ (!isfloat[et] && n->etype == ODIV) ||
+ n->etype == OMOD) {
l = safeexpr(n->left, init);
a = l;
if(a->op == OINDEXMAP) {
@@ -794,15 +924,24 @@ walkexpr(Node **np, NodeList **init)
typecheck(&r, Etop);
walkexpr(&r, init);
n = r;
+ goto ret;
}
+ if(n->etype == OLSH || n->etype == ORSH)
+ goto shiftwalked;
goto ret;
case OANDNOT:
walkexpr(&n->left, init);
- walkexpr(&n->right, init);
n->op = OAND;
n->right = nod(OCOM, n->right, N);
typecheck(&n->right, Erv);
+ walkexpr(&n->right, init);
+ goto ret;
+
+ case OMUL:
+ walkexpr(&n->left, init);
+ walkexpr(&n->right, init);
+ walkmul(&n, init);
goto ret;
case ODIV:
@@ -821,63 +960,80 @@ walkexpr(Node **np, NodeList **init)
n = conv(n, t);
goto ret;
}
+ // Nothing to do for float divisions.
+ if(isfloat[et])
+ goto ret;
+
+ // Try rewriting as shifts or magic multiplies.
+ walkdiv(&n, init);
+
/*
- * rewrite div and mod into function calls
+ * rewrite 64-bit div and mod into function calls
* on 32-bit architectures.
*/
- if(widthptr > 4 || (et != TUINT64 && et != TINT64))
- goto ret;
- if(et == TINT64)
- strcpy(namebuf, "int64");
- else
- strcpy(namebuf, "uint64");
- if(n->op == ODIV)
- strcat(namebuf, "div");
- else
- strcat(namebuf, "mod");
- n = mkcall(namebuf, n->type, init,
- conv(n->left, types[et]), conv(n->right, types[et]));
+ switch(n->op) {
+ case OMOD:
+ case ODIV:
+ if(widthptr > 4 || (et != TUINT64 && et != TINT64))
+ goto ret;
+ if(et == TINT64)
+ strcpy(namebuf, "int64");
+ else
+ strcpy(namebuf, "uint64");
+ if(n->op == ODIV)
+ strcat(namebuf, "div");
+ else
+ strcat(namebuf, "mod");
+ n = mkcall(namebuf, n->type, init,
+ conv(n->left, types[et]), conv(n->right, types[et]));
+ break;
+ default:
+ break;
+ }
goto ret;
case OINDEX:
walkexpr(&n->left, init);
+ // save the original node for bounds checking elision.
+ // If it was a ODIV/OMOD walk might rewrite it.
+ r = n->right;
walkexpr(&n->right, init);
// if range of type cannot exceed static array bound,
- // disable bounds check
- if(isfixedarray(n->left->type))
- if(!issigned[n->right->type->etype])
- if(n->right->type->width < 4)
- if((1<<(8*n->right->type->width)) <= n->left->type->bound)
- n->etype = 1;
-
- if(isconst(n->left, CTSTR))
- if(!issigned[n->right->type->etype])
- if(n->right->type->width < 4)
- if((1<<(8*n->right->type->width)) <= n->left->val.u.sval->len)
- n->etype = 1;
-
- // check for static out of bounds
- if(isconst(n->right, CTINT) && !n->etype) {
- v = mpgetfix(n->right->val.u.xval);
- len = 1LL<<60;
- t = n->left->type;
- if(isconst(n->left, CTSTR))
- len = n->left->val.u.sval->len;
- if(t != T && isptr[t->etype])
- t = t->type;
- if(isfixedarray(t))
- len = t->bound;
- if(v < 0 || v >= (1LL<<31) || v >= len)
+ // disable bounds check.
+ if(n->bounded)
+ goto ret;
+ t = n->left->type;
+ if(t != T && isptr[t->etype])
+ t = t->type;
+ if(isfixedarray(t)) {
+ n->bounded = bounded(r, t->bound);
+ if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
+ warn("index bounds check elided");
+ if(smallintconst(n->right) && !n->bounded)
yyerror("index out of bounds");
- else if(isconst(n->left, CTSTR)) {
- // replace "abc"[2] with 'b'.
- // delayed until now because "abc"[2] is not
- // an ideal constant.
- nodconst(n, n->type, n->left->val.u.sval->s[v]);
- n->typecheck = 1;
+ } else if(isconst(n->left, CTSTR)) {
+ n->bounded = bounded(r, n->left->val.u.sval->len);
+ if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
+ warn("index bounds check elided");
+ if(smallintconst(n->right)) {
+ if(!n->bounded)
+ yyerror("index out of bounds");
+ else {
+ // replace "abc"[2] with 'b'.
+ // delayed until now because "abc"[2] is not
+ // an ideal constant.
+ v = mpgetfix(n->right->val.u.xval);
+ nodconst(n, n->type, n->left->val.u.sval->s[v]);
+ n->typecheck = 1;
+ }
}
}
+
+ if(isconst(n->right, CTINT))
+ if(mpcmpfixfix(n->right->val.u.xval, &mpzero) < 0 ||
+ mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
+ yyerror("index out of bounds");
goto ret;
case OINDEXMAP:
@@ -895,95 +1051,29 @@ walkexpr(Node **np, NodeList **init)
goto ret;
case OSLICE:
+ if(n->right != N && n->right->left == N && n->right->right == N) { // noop
+ walkexpr(&n->left, init);
+ n = n->left;
+ goto ret;
+ }
+ // fallthrough
case OSLICEARR:
+ case OSLICESTR:
+ if(n->right == N) // already processed
+ goto ret;
+
walkexpr(&n->left, init);
- n->left = safeexpr(n->left, init);
+ // cgen_slice can't handle string literals as source
+ // TODO the OINDEX case is a bug elsewhere that needs to be traced. it causes a crash on ([2][]int{ ... })[1][lo:hi]
+ if((n->op == OSLICESTR && n->left->op == OLITERAL) || (n->left->op == OINDEX))
+ n->left = copyexpr(n->left, n->left->type, init);
+ else
+ n->left = safeexpr(n->left, init);
walkexpr(&n->right->left, init);
n->right->left = safeexpr(n->right->left, init);
walkexpr(&n->right->right, init);
n->right->right = safeexpr(n->right->right, init);
-
- len = 1LL<<60;
- t = n->left->type;
- if(t != T && isptr[t->etype])
- t = t->type;
- if(isfixedarray(t))
- len = t->bound;
-
- // check for static out of bounds
- // NOTE: v > len not v >= len.
- v1 = -1;
- v2 = -1;
- if(isconst(n->right->left, CTINT)) {
- v1 = mpgetfix(n->right->left->val.u.xval);
- if(v1 < 0 || v1 >= (1LL<<31) || v1 > len) {
- yyerror("slice index out of bounds");
- v1 = -1;
- }
- }
- if(isconst(n->right->right, CTINT)) {
- v2 = mpgetfix(n->right->right->val.u.xval);
- if(v2 < 0 || v2 >= (1LL<<31) || v2 > len) {
- yyerror("slice index out of bounds");
- v2 = -1;
- }
- }
- if(v1 >= 0 && v2 >= 0 && v1 > v2)
- yyerror("inverted slice range");
-
- if(n->op == OSLICEARR)
- goto slicearray;
-
- // dynamic slice
- // sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any)
- // sliceslice1(old []any, lb uint64, width uint64) (ary []any)
- t = n->type;
- et = n->etype;
- if(n->right->left == N)
- l = nodintconst(0);
- else
- l = conv(n->right->left, types[TUINT64]);
- if(n->right->right != N) {
- fn = syslook("sliceslice", 1);
- argtype(fn, t->type); // any-1
- argtype(fn, t->type); // any-2
- n = mkcall1(fn, t, init,
- n->left,
- l,
- conv(n->right->right, types[TUINT64]),
- nodintconst(t->type->width));
- } else {
- fn = syslook("sliceslice1", 1);
- argtype(fn, t->type); // any-1
- argtype(fn, t->type); // any-2
- n = mkcall1(fn, t, init,
- n->left,
- l,
- nodintconst(t->type->width));
- }
- n->etype = et; // preserve no-typecheck flag from OSLICE to the slice* call.
- goto ret;
-
- slicearray:
- // static slice
- // slicearray(old *any, uint64 nel, lb uint64, hb uint64, width uint64) (ary []any)
- t = n->type;
- fn = syslook("slicearray", 1);
- argtype(fn, n->left->type->type); // any-1
- argtype(fn, t->type); // any-2
- if(n->right->left == N)
- l = nodintconst(0);
- else
- l = conv(n->right->left, types[TUINT64]);
- if(n->right->right == N)
- r = nodintconst(n->left->type->type->bound);
- else
- r = conv(n->right->right, types[TUINT64]);
- n = mkcall1(fn, t, init,
- n->left, nodintconst(n->left->type->type->bound),
- l,
- r,
- nodintconst(t->type->width));
+ n = sliceany(n, init); // chops n->right, sets n->list
goto ret;
case OADDR:
@@ -1031,27 +1121,34 @@ walkexpr(Node **np, NodeList **init)
goto ret;
}
- // prepare for rewrite below
if(n->etype == OEQ || n->etype == ONE) {
+ // prepare for rewrite below
n->left = cheapexpr(n->left, init);
n->right = cheapexpr(n->right, init);
- }
- // sys_cmpstring(s1, s2) :: 0
- r = mkcall("cmpstring", types[TINT], init,
- conv(n->left, types[TSTRING]),
- conv(n->right, types[TSTRING]));
- r = nod(n->etype, r, nodintconst(0));
+ r = mkcall("eqstring", types[TBOOL], init,
+ conv(n->left, types[TSTRING]),
+ conv(n->right, types[TSTRING]));
- // quick check of len before full compare for == or !=
- if(n->etype == OEQ || n->etype == ONE) {
- if(n->etype == OEQ)
+ // quick check of len before full compare for == or !=
+ if(n->etype == OEQ) {
+ // len(left) == len(right) && eqstring(left, right)
r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
- else
+ } else {
+ // len(left) != len(right) || !eqstring(left, right)
+ r = nod(ONOT, r, N);
r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
+ }
typecheck(&r, Erv);
walkexpr(&r, nil);
+ } else {
+ // sys_cmpstring(s1, s2) :: 0
+ r = mkcall("cmpstring", types[TINT], init,
+ conv(n->left, types[TSTRING]),
+ conv(n->right, types[TSTRING]));
+ r = nod(n->etype, r, nodintconst(0));
}
+
typecheck(&r, Erv);
if(n->type->etype != TBOOL) fatal("cmp %T", n->type);
r->type = n->type;
@@ -1061,25 +1158,7 @@ walkexpr(Node **np, NodeList **init)
case OADDSTR:
n = addstr(n, init);
goto ret;
-
- case OSLICESTR:
- // sys_slicestring(s, lb, hb)
- if(n->right->left == N)
- l = nodintconst(0);
- else
- l = conv(n->right->left, types[TINT]);
- if(n->right->right) {
- n = mkcall("slicestring", n->type, init,
- conv(n->left, types[TSTRING]),
- l,
- conv(n->right->right, types[TINT]));
- } else {
- n = mkcall("slicestring1", n->type, init,
- conv(n->left, types[TSTRING]),
- l);
- }
- goto ret;
-
+
case OAPPEND:
if(n->isddd) {
if(istype(n->type->type, TUINT8) && istype(n->list->next->n->type, TSTRING))
@@ -1177,6 +1256,9 @@ walkexpr(Node **np, NodeList **init)
fn = syslook("efaceeq", 1);
else
fn = syslook("ifaceeq", 1);
+
+ n->right = cheapexpr(n->right, init);
+ n->left = cheapexpr(n->left, init);
argtype(fn, n->right->type);
argtype(fn, n->left->type);
r = mkcall1(fn, n->type, init, n->left, n->right);
@@ -1189,7 +1271,7 @@ walkexpr(Node **np, NodeList **init)
else
r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
typecheck(&r, Erv);
- walkexpr(&r, nil);
+ walkexpr(&r, init);
r->type = n->type;
n = r;
goto ret;
@@ -1226,9 +1308,16 @@ ret:
static Node*
ascompatee1(int op, Node *l, Node *r, NodeList **init)
{
+ Node *n;
USED(op);
+
+ // convas will turn map assigns into function calls,
+ // making it impossible for reorder3 to work.
+ n = nod(OAS, l, r);
+ if(l->op == OINDEXMAP)
+ return n;
- return convas(nod(OAS, l, r), init);
+ return convas(n, init);
}
static NodeList*
@@ -1249,12 +1338,16 @@ ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
lr->n = safeexpr(lr->n, init);
nn = nil;
- for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next)
+ for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) {
+ // Do not generate 'x = x' during return. See issue 4014.
+ if(op == ORETURN && ll->n == lr->n)
+ continue;
nn = list(nn, ascompatee1(op, ll->n, lr->n, init));
+ }
// cannot happen: caller checked that lists had same length
if(ll || lr)
- yyerror("error in shape across %+H %O %+H", nl, op, nr);
+ yyerror("error in shape across %+H %O %+H / %d %d [%s]", nl, op, nr, count(nl), count(nr), curfn->nname->sym->name);
return nn;
}
@@ -1826,13 +1919,14 @@ static int aliased(Node*, NodeList*, NodeList*);
static NodeList*
reorder3(NodeList *all)
{
- NodeList *list, *early;
+ NodeList *list, *early, *mapinit;
Node *l;
// If a needed expression may be affected by an
// earlier assignment, make an early copy of that
// expression and use the copy instead.
early = nil;
+ mapinit = nil;
for(list=all; list; list=list->next) {
l = list->n->left;
@@ -1856,8 +1950,11 @@ reorder3(NodeList *all)
case ONAME:
break;
case OINDEX:
+ case OINDEXMAP:
reorder3save(&l->left, all, list, &early);
reorder3save(&l->right, all, list, &early);
+ if(l->op == OINDEXMAP)
+ list->n = convas(list->n, &mapinit);
break;
case OIND:
case ODOTPTR:
@@ -1868,6 +1965,7 @@ reorder3(NodeList *all)
reorder3save(&list->n->right, all, list, &early);
}
+ early = concat(mapinit, early);
return concat(early, all);
}
@@ -2119,6 +2217,8 @@ paramstoheap(Type **argin, int out)
nn = nil;
for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
v = t->nname;
+ if(v && v->sym && v->sym->name[0] == '~')
+ v = N;
if(v == N && out && hasdefer) {
// Defer might stop a panic and show the
// return values as they exist at the time of panic.
@@ -2395,12 +2495,12 @@ append(Node *n, NodeList **init)
l = list(l, nod(OAS, nn, nod(OLEN, ns, N))); // n = len(s)
nx = nod(OSLICE, ns, nod(OKEY, N, nod(OADD, nn, na))); // ...s[:n+argc]
- nx->etype = 1; // disable bounds check
+ nx->bounded = 1;
l = list(l, nod(OAS, ns, nx)); // s = s[:n+argc]
for (a = n->list->next; a != nil; a = a->next) {
nx = nod(OINDEX, ns, nn); // s[n] ...
- nx->etype = 1; // disable bounds check
+ nx->bounded = 1;
l = list(l, nod(OAS, nx, a->n)); // s[n] = arg
if (a->next != nil)
l = list(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))); // n = n + 1
@@ -2412,6 +2512,151 @@ append(Node *n, NodeList **init)
return ns;
}
+
+// Generate frontend part for OSLICE[ARR|STR]
+//
+static Node*
+sliceany(Node* n, NodeList **init)
+{
+ int bounded;
+ Node *src, *lb, *hb, *bound, *chk, *chk1, *chk2;
+ int64 lbv, hbv, bv, w;
+ Type *bt;
+
+// print("before sliceany: %+N\n", n);
+
+ src = n->left;
+ lb = n->right->left;
+ hb = n->right->right;
+
+ bounded = n->etype;
+
+ if(n->op == OSLICESTR)
+ bound = nod(OLEN, src, N);
+ else
+ bound = nod(OCAP, src, N);
+
+ typecheck(&bound, Erv);
+ walkexpr(&bound, init); // if src is an array, bound will be a const now.
+
+ // static checks if possible
+ bv = 1LL<<50;
+ if(isconst(bound, CTINT)) {
+ if(!smallintconst(bound))
+ yyerror("array len too large");
+ else
+ bv = mpgetfix(bound->val.u.xval);
+ }
+
+ if(isconst(hb, CTINT)) {
+ hbv = mpgetfix(hb->val.u.xval);
+ if(hbv < 0 || hbv > bv) {
+ yyerror("slice index out of bounds");
+ hbv = -1;
+ }
+ }
+ if(isconst(lb, CTINT)) {
+ lbv = mpgetfix(lb->val.u.xval);
+ if(lbv < 0 || lbv > bv) {
+ yyerror("slice index out of bounds");
+ lbv = -1;
+ }
+ if(lbv == 0)
+ lb = N;
+ }
+
+ // dynamic checks convert all bounds to unsigned to save us the bound < 0 comparison
+ // generate
+ // if hb > bound || lb > hb { panicslice() }
+ chk = N;
+ chk1 = N;
+ chk2 = N;
+
+ bt = types[simtype[TUINT]];
+ if(hb != N && hb->type->width > 4)
+ bt = types[TUINT64];
+ if(lb != N && lb->type->width > 4)
+ bt = types[TUINT64];
+
+ bound = cheapexpr(conv(bound, bt), init);
+
+ if(hb != N) {
+ hb = cheapexpr(conv(hb, bt), init);
+ if(!bounded)
+ chk1 = nod(OLT, bound, hb);
+ } else if(n->op == OSLICEARR) {
+ hb = bound;
+ } else {
+ hb = nod(OLEN, src, N);
+ typecheck(&hb, Erv);
+ walkexpr(&hb, init);
+ hb = cheapexpr(conv(hb, bt), init);
+ }
+
+ if(lb != N) {
+ lb = cheapexpr(conv(lb, bt), init);
+ if(!bounded)
+ chk2 = nod(OLT, hb, lb);
+ }
+
+ if(chk1 != N || chk2 != N) {
+ chk = nod(OIF, N, N);
+ chk->nbody = list1(mkcall("panicslice", T, init));
+ if(chk1 != N)
+ chk->ntest = chk1;
+ if(chk2 != N) {
+ if(chk->ntest == N)
+ chk->ntest = chk2;
+ else
+ chk->ntest = nod(OOROR, chk->ntest, chk2);
+ }
+ typecheck(&chk, Etop);
+ walkstmt(&chk);
+ *init = concat(*init, chk->ninit);
+ chk->ninit = nil;
+ *init = list(*init, chk);
+ }
+
+ // prepare new cap, len and offs for backend cgen_slice
+ // cap = bound [ - lo ]
+ n->right = N;
+ n->list = nil;
+ if(lb == N)
+ bound = conv(bound, types[simtype[TUINT]]);
+ else
+ bound = nod(OSUB, conv(bound, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
+ typecheck(&bound, Erv);
+ walkexpr(&bound, init);
+ n->list = list(n->list, bound);
+
+ // len = hi [ - lo]
+ if(lb == N)
+ hb = conv(hb, types[simtype[TUINT]]);
+ else
+ hb = nod(OSUB, conv(hb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
+ typecheck(&hb, Erv);
+ walkexpr(&hb, init);
+ n->list = list(n->list, hb);
+
+ // offs = [width *] lo, but omit if zero
+ if(lb != N) {
+ if(n->op == OSLICESTR)
+ w = 1;
+ else
+ w = n->type->type->width;
+ lb = conv(lb, types[TUINTPTR]);
+ if(w > 1)
+ lb = nod(OMUL, nodintconst(w), lb);
+ typecheck(&lb, Erv);
+ walkexpr(&lb, init);
+ n->list = list(n->list, lb);
+ }
+
+// print("after sliceany: %+N\n", n);
+
+ return n;
+}
+
static Node*
eqfor(Type *t)
{
@@ -2531,6 +2776,8 @@ walkcompare(Node **np, NodeList **init)
// Struct of four or fewer fields.
// Inline comparisons.
for(t1=t->type; t1; t1=t1->down) {
+ if(isblanksym(t1->sym))
+ continue;
li = nod(OXDOT, l, newname(t1->sym));
ri = nod(OXDOT, r, newname(t1->sym));
a = nod(n->op, li, ri);
@@ -2596,3 +2843,591 @@ hard:
*np = r;
return;
}
+
+static int
+samecheap(Node *a, Node *b)
+{
+ if(a == N || b == N || a->op != b->op)
+ return 0;
+
+ switch(a->op) {
+ case ONAME:
+ return a == b;
+ // TODO: Could do more here, but maybe this is enough.
+ // It's all cheapexpr does.
+ }
+ return 0;
+}
+
+static void
+walkrotate(Node **np)
+{
+ int w, sl, sr, s;
+ Node *l, *r;
+ Node *n;
+
+ n = *np;
+
+ // Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value.
+ l = n->left;
+ r = n->right;
+ if((n->op != OOR && n->op != OXOR) ||
+ (l->op != OLSH && l->op != ORSH) ||
+ (r->op != OLSH && r->op != ORSH) ||
+ n->type == T || issigned[n->type->etype] ||
+ l->op == r->op) {
+ return;
+ }
+
+ // Want same, side effect-free expression on lhs of both shifts.
+ if(!samecheap(l->left, r->left))
+ return;
+
+ // Constants adding to width?
+ w = l->type->width * 8;
+ if(smallintconst(l->right) && smallintconst(r->right)) {
+ if((sl=mpgetfix(l->right->val.u.xval)) >= 0 && (sr=mpgetfix(r->right->val.u.xval)) >= 0 && sl+sr == w)
+ goto yes;
+ return;
+ }
+
+ // TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
+ return;
+
+yes:
+ // Rewrite left shift half to left rotate.
+ if(l->op == OLSH)
+ n = l;
+ else
+ n = r;
+ n->op = OLROT;
+
+ // Remove rotate 0 and rotate w.
+ s = mpgetfix(n->right->val.u.xval);
+ if(s == 0 || s == w)
+ n = n->left;
+
+ *np = n;
+ return;
+}
+
+/*
+ * walkmul rewrites integer multiplication by powers of two as shifts.
+ */
+static void
+walkmul(Node **np, NodeList **init)
+{
+ Node *n, *nl, *nr;
+ int pow, neg, w;
+
+ n = *np;
+ if(!isint[n->type->etype])
+ return;
+
+ if(n->right->op == OLITERAL) {
+ nl = n->left;
+ nr = n->right;
+ } else if(n->left->op == OLITERAL) {
+ nl = n->right;
+ nr = n->left;
+ } else
+ return;
+
+ neg = 0;
+
+ // x*0 is 0 (and side effects of x).
+ if(mpgetfix(nr->val.u.xval) == 0) {
+ cheapexpr(nl, init);
+ nodconst(n, n->type, 0);
+ goto ret;
+ }
+
+ // nr is a constant.
+ pow = powtwo(nr);
+ if(pow < 0)
+ return;
+ if(pow >= 1000) {
+ // negative power of 2, like -16
+ neg = 1;
+ pow -= 1000;
+ }
+
+ w = nl->type->width*8;
+ if(pow+1 >= w)// too big, shouldn't happen
+ return;
+
+ nl = cheapexpr(nl, init);
+
+ if(pow == 0) {
+ // x*1 is x
+ n = nl;
+ goto ret;
+ }
+
+ n = nod(OLSH, nl, nodintconst(pow));
+
+ret:
+ if(neg)
+ n = nod(OMINUS, n, N);
+
+ typecheck(&n, Erv);
+ walkexpr(&n, init);
+ *np = n;
+}
+
+/*
+ * walkdiv rewrites division by a constant as less expensive
+ * operations.
+ */
+static void
+walkdiv(Node **np, NodeList **init)
+{
+ Node *n, *nl, *nr, *nc;
+ Node *n1, *n2, *n3, *n4;
+ int pow; // if >= 0, nr is 1<<pow
+ int s; // 1 if nr is negative.
+ int w;
+ Type *twide;
+ Magic m;
+
+ n = *np;
+ if(n->right->op != OLITERAL)
+ return;
+ // nr is a constant.
+ nl = cheapexpr(n->left, init);
+ nr = n->right;
+
+ // special cases of mod/div
+ // by a constant
+ w = nl->type->width*8;
+ s = 0;
+ pow = powtwo(nr);
+ if(pow >= 1000) {
+ // negative power of 2
+ s = 1;
+ pow -= 1000;
+ }
+
+ if(pow+1 >= w) {
+ // divisor too large.
+ return;
+ }
+ if(pow < 0) {
+ goto divbymul;
+ }
+
+ switch(pow) {
+ case 0:
+ if(n->op == OMOD) {
+ // nl % 1 is zero.
+ nodconst(n, n->type, 0);
+ } else if(s) {
+ // divide by -1
+ n->op = OMINUS;
+ n->right = N;
+ } else {
+ // divide by 1
+ n = nl;
+ }
+ break;
+ default:
+ if(issigned[n->type->etype]) {
+ if(n->op == OMOD) {
+ // signed modulo 2^pow is like ANDing
+ // with the last pow bits, but if nl < 0,
+ // nl & (2^pow-1) is (nl+1)%2^pow - 1.
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[simtype[TUINT]], w-1);
+ n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
+ if(pow == 1) {
+ typecheck(&n1, Erv);
+ n1 = cheapexpr(n1, init);
+ // n = (nl+ε)&1 -ε where ε=1 iff nl<0.
+ n2 = nod(OSUB, nl, n1);
+ nc = nod(OXXX, N, N);
+ nodconst(nc, nl->type, 1);
+ n3 = nod(OAND, n2, nc);
+ n = nod(OADD, n3, n1);
+ } else {
+ // n = (nl+ε)&(nr-1) - ε where ε=2^pow-1 iff nl<0.
+ nc = nod(OXXX, N, N);
+ nodconst(nc, nl->type, (1LL<<pow)-1);
+ n2 = nod(OAND, n1, nc); // n2 = 2^pow-1 iff nl<0.
+ typecheck(&n2, Erv);
+ n2 = cheapexpr(n2, init);
+
+ n3 = nod(OADD, nl, n2);
+ n4 = nod(OAND, n3, nc);
+ n = nod(OSUB, n4, n2);
+ }
+ break;
+ } else {
+ // arithmetic right shift does not give the correct rounding.
+ // if nl >= 0, nl >> n == nl / nr
+ // if nl < 0, we want to add 2^n-1 first.
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[simtype[TUINT]], w-1);
+ n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
+ if(pow == 1) {
+ // nl+1 is nl-(-1)
+ n->left = nod(OSUB, nl, n1);
+ } else {
+ // Do a logical right right on -1 to keep pow bits.
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[simtype[TUINT]], w-pow);
+ n2 = nod(ORSH, conv(n1, tounsigned(nl->type)), nc);
+ n->left = nod(OADD, nl, conv(n2, nl->type));
+ }
+ // n = (nl + 2^pow-1) >> pow
+ n->op = ORSH;
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[simtype[TUINT]], pow);
+ n->right = nc;
+ n->typecheck = 0;
+ }
+ if(s)
+ n = nod(OMINUS, n, N);
+ break;
+ }
+ nc = nod(OXXX, N, N);
+ if(n->op == OMOD) {
+ // n = nl & (nr-1)
+ n->op = OAND;
+ nodconst(nc, nl->type, mpgetfix(nr->val.u.xval)-1);
+ } else {
+ // n = nl >> pow
+ n->op = ORSH;
+ nodconst(nc, types[simtype[TUINT]], pow);
+ }
+ n->typecheck = 0;
+ n->right = nc;
+ break;
+ }
+ goto ret;
+
+divbymul:
+ // try to do division by multiply by (2^w)/d
+ // see hacker's delight chapter 10
+ // TODO: support 64-bit magic multiply here.
+ m.w = w;
+ if(issigned[nl->type->etype]) {
+ m.sd = mpgetfix(nr->val.u.xval);
+ smagic(&m);
+ } else {
+ m.ud = mpgetfix(nr->val.u.xval);
+ umagic(&m);
+ }
+ if(m.bad)
+ return;
+
+ // We have a quick division method so use it
+ // for modulo too.
+ if(n->op == OMOD)
+ goto longmod;
+
+ switch(simtype[nl->type->etype]) {
+ default:
+ return;
+
+ case TUINT8:
+ case TUINT16:
+ case TUINT32:
+ // n1 = nl * magic >> w (HMUL)
+ nc = nod(OXXX, N, N);
+ nodconst(nc, nl->type, m.um);
+ n1 = nod(OMUL, nl, nc);
+ typecheck(&n1, Erv);
+ n1->op = OHMUL;
+ if(m.ua) {
+ // Select a Go type with (at least) twice the width.
+ switch(simtype[nl->type->etype]) {
+ default:
+ return;
+ case TUINT8:
+ case TUINT16:
+ twide = types[TUINT32];
+ break;
+ case TUINT32:
+ twide = types[TUINT64];
+ break;
+ case TINT8:
+ case TINT16:
+ twide = types[TINT32];
+ break;
+ case TINT32:
+ twide = types[TINT64];
+ break;
+ }
+
+ // add numerator (might overflow).
+ // n2 = (n1 + nl)
+ n2 = nod(OADD, conv(n1, twide), conv(nl, twide));
+
+ // shift by m.s
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[TUINT], m.s);
+ n = conv(nod(ORSH, n2, nc), nl->type);
+ } else {
+ // n = n1 >> m.s
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[TUINT], m.s);
+ n = nod(ORSH, n1, nc);
+ }
+ break;
+
+ case TINT8:
+ case TINT16:
+ case TINT32:
+ // n1 = nl * magic >> w
+ nc = nod(OXXX, N, N);
+ nodconst(nc, nl->type, m.sm);
+ n1 = nod(OMUL, nl, nc);
+ typecheck(&n1, Erv);
+ n1->op = OHMUL;
+ if(m.sm < 0) {
+ // add the numerator.
+ n1 = nod(OADD, n1, nl);
+ }
+ // shift by m.s
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[TUINT], m.s);
+ n2 = conv(nod(ORSH, n1, nc), nl->type);
+ // add 1 iff n1 is negative.
+ nc = nod(OXXX, N, N);
+ nodconst(nc, types[TUINT], w-1);
+ n3 = nod(ORSH, nl, nc); // n4 = -1 iff n1 is negative.
+ n = nod(OSUB, n2, n3);
+ // apply sign.
+ if(m.sd < 0)
+ n = nod(OMINUS, n, N);
+ break;
+ }
+ goto ret;
+
+longmod:
+ // rewrite as A%B = A - (A/B*B).
+ n1 = nod(ODIV, nl, nr);
+ n2 = nod(OMUL, n1, nr);
+ n = nod(OSUB, nl, n2);
+ goto ret;
+
+ret:
+ typecheck(&n, Erv);
+ walkexpr(&n, init);
+ *np = n;
+}
+
+// return 1 if integer n must be in range [0, max), 0 otherwise
+static int
+bounded(Node *n, int64 max)
+{
+ int64 v;
+ int32 bits;
+ int sign;
+
+ if(n->type == T || !isint[n->type->etype])
+ return 0;
+
+ sign = issigned[n->type->etype];
+ bits = 8*n->type->width;
+
+ if(smallintconst(n)) {
+ v = mpgetfix(n->val.u.xval);
+ return 0 <= v && v < max;
+ }
+
+ switch(n->op) {
+ case OAND:
+ v = -1;
+ if(smallintconst(n->left)) {
+ v = mpgetfix(n->left->val.u.xval);
+ } else if(smallintconst(n->right)) {
+ v = mpgetfix(n->right->val.u.xval);
+ }
+ if(0 <= v && v < max)
+ return 1;
+ break;
+
+ case OMOD:
+ if(!sign && smallintconst(n->right)) {
+ v = mpgetfix(n->right->val.u.xval);
+ if(0 <= v && v <= max)
+ return 1;
+ }
+ break;
+
+ case ODIV:
+ if(!sign && smallintconst(n->right)) {
+ v = mpgetfix(n->right->val.u.xval);
+ while(bits > 0 && v >= 2) {
+ bits--;
+ v >>= 1;
+ }
+ }
+ break;
+
+ case ORSH:
+ if(!sign && smallintconst(n->right)) {
+ v = mpgetfix(n->right->val.u.xval);
+ if(v > bits)
+ return 1;
+ bits -= v;
+ }
+ break;
+ }
+
+ if(!sign && bits <= 62 && (1LL<<bits) <= max)
+ return 1;
+
+ return 0;
+}
+
+void
+usefield(Node *n)
+{
+ Type *field, *l;
+
+ if(!fieldtrack_enabled)
+ return;
+
+ switch(n->op) {
+ default:
+ fatal("usefield %O", n->op);
+ case ODOT:
+ case ODOTPTR:
+ break;
+ }
+
+ field = n->paramfld;
+ if(field == T)
+ fatal("usefield %T %S without paramfld", n->left->type, n->right->sym);
+ if(field->note == nil || strstr(field->note->s, "go:\"track\"") == nil)
+ return;
+
+ // dedup on list
+ if(field->lastfn == curfn)
+ return;
+ field->lastfn = curfn;
+ field->outer = n->left->type;
+ if(isptr[field->outer->etype])
+ field->outer = field->outer->type;
+ if(field->outer->sym == S)
+ yyerror("tracked field must be in named struct type");
+ if(!exportname(field->sym->name))
+ yyerror("tracked field must be exported (upper case)");
+
+ l = typ(0);
+ l->type = field;
+ l->down = curfn->paramfld;
+ curfn->paramfld = l;
+}
+
+static int
+candiscardlist(NodeList *l)
+{
+ for(; l; l=l->next)
+ if(!candiscard(l->n))
+ return 0;
+ return 1;
+}
+
+int
+candiscard(Node *n)
+{
+ if(n == N)
+ return 1;
+
+ switch(n->op) {
+ default:
+ return 0;
+
+ case ONAME:
+ case ONONAME:
+ case OTYPE:
+ case OPACK:
+ case OLITERAL:
+ case OADD:
+ case OSUB:
+ case OOR:
+ case OXOR:
+ case OADDSTR:
+ case OADDR:
+ case OANDAND:
+ case OARRAYBYTESTR:
+ case OARRAYRUNESTR:
+ case OSTRARRAYBYTE:
+ case OSTRARRAYRUNE:
+ case OCAP:
+ case OCMPIFACE:
+ case OCMPSTR:
+ case OCOMPLIT:
+ case OMAPLIT:
+ case OSTRUCTLIT:
+ case OARRAYLIT:
+ case OPTRLIT:
+ case OCONV:
+ case OCONVIFACE:
+ case OCONVNOP:
+ case ODOT:
+ case OEQ:
+ case ONE:
+ case OLT:
+ case OLE:
+ case OGT:
+ case OGE:
+ case OKEY:
+ case OLEN:
+ case OMUL:
+ case OLSH:
+ case ORSH:
+ case OAND:
+ case OANDNOT:
+ case ONEW:
+ case ONOT:
+ case OCOM:
+ case OPLUS:
+ case OMINUS:
+ case OOROR:
+ case OPAREN:
+ case ORUNESTR:
+ case OREAL:
+ case OIMAG:
+ case OCOMPLEX:
+ // Discardable as long as the subpieces are.
+ break;
+
+ case ODIV:
+ case OMOD:
+ // Discardable as long as we know it's not division by zero.
+ if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0)
+ break;
+ if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0)
+ break;
+ return 0;
+
+ case OMAKECHAN:
+ case OMAKEMAP:
+ // Discardable as long as we know it won't fail because of a bad size.
+ if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0)
+ break;
+ return 0;
+
+ case OMAKESLICE:
+ // Difficult to tell what sizes are okay.
+ return 0;
+ }
+
+ if(!candiscard(n->left) ||
+ !candiscard(n->right) ||
+ !candiscard(n->ntest) ||
+ !candiscard(n->nincr) ||
+ !candiscardlist(n->ninit) ||
+ !candiscardlist(n->nbody) ||
+ !candiscardlist(n->nelse) ||
+ !candiscardlist(n->list) ||
+ !candiscardlist(n->rlist)) {
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/src/cmd/gc/y.tab.c b/src/cmd/gc/y.tab.c
index 97bf233eb..75175455e 100644
--- a/src/cmd/gc/y.tab.c
+++ b/src/cmd/gc/y.tab.c
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,7 +29,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@@ -44,7 +47,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.3"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -52,52 +55,11 @@
/* Pure parsers. */
#define YYPURE 0
-/* Push parsers. */
-#define YYPUSH 0
-
-/* Pull parsers. */
-#define YYPULL 1
-
/* Using locations. */
#define YYLSP_NEEDED 0
-/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 20 "go.y"
-
-#include <u.h>
-#include <stdio.h> /* if we don't, bison will, and go.h re-#defines getc */
-#include <libc.h>
-#include "go.h"
-
-static void fixlbrace(int);
-
-
-/* Line 268 of yacc.c */
-#line 81 "y.tab.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 1
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -106,10 +68,10 @@ static void fixlbrace(int);
enum yytokentype {
LLITERAL = 258,
LASOP = 259,
- LBREAK = 260,
- LCASE = 261,
- LCHAN = 262,
- LCOLAS = 263,
+ LCOLAS = 260,
+ LBREAK = 261,
+ LCASE = 262,
+ LCHAN = 263,
LCONST = 264,
LCONTINUE = 265,
LDDD = 266,
@@ -158,10 +120,10 @@ static void fixlbrace(int);
/* Tokens. */
#define LLITERAL 258
#define LASOP 259
-#define LBREAK 260
-#define LCASE 261
-#define LCHAN 262
-#define LCOLAS 263
+#define LCOLAS 260
+#define LBREAK 261
+#define LCASE 262
+#define LCHAN 263
#define LCONST 264
#define LCONTINUE 265
#define LDDD 266
@@ -209,36 +171,61 @@ static void fixlbrace(int);
+/* Copy the first part of user declarations. */
+#line 20 "go.y"
+
+#include <u.h>
+#include <stdio.h> /* if we don't, bison will, and go.h re-#defines getc */
+#include <libc.h>
+#include "go.h"
+
+static void fixlbrace(int);
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 293 of yacc.c */
#line 28 "go.y"
-
+{
Node* node;
NodeList* list;
Type* type;
Sym* sym;
struct Val val;
int i;
-
-
-
-/* Line 293 of yacc.c */
-#line 230 "y.tab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 193 of yacc.c. */
+#line 216 "y.tab.c"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
+
/* Copy the second part of user declarations. */
-/* Line 343 of yacc.c */
-#line 242 "y.tab.c"
+/* Line 216 of yacc.c. */
+#line 229 "y.tab.c"
#ifdef short
# undef short
@@ -313,14 +300,14 @@ typedef short int yytype_int16;
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static int
-YYID (int yyi)
+YYID (int i)
#else
static int
-YYID (yyi)
- int yyi;
+YYID (i)
+ int i;
#endif
{
- return yyi;
+ return i;
}
#endif
@@ -341,11 +328,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# endif
@@ -368,24 +355,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+# if (defined __cplusplus && ! defined _STDLIB_H \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@@ -401,9 +388,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- yytype_int16 yyss_alloc;
- YYSTYPE yyvs_alloc;
-};
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -414,27 +401,6 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
@@ -452,21 +418,38 @@ union yyalloc
while (YYID (0))
# endif
# endif
-#endif /* !YYCOPY_NEEDED */
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 4
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 2131
+#define YYLAST 2194
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 76
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 138
+#define YYNNTS 142
/* YYNRULES -- Number of rules. */
-#define YYNRULES 344
+#define YYNRULES 349
/* YYNRULES -- Number of states. */
-#define YYNSTATES 653
+#define YYNSTATES 663
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
@@ -524,148 +507,150 @@ static const yytype_uint16 yyprhs[] =
162, 164, 168, 172, 176, 179, 182, 186, 192, 198,
201, 202, 207, 208, 212, 213, 216, 217, 222, 227,
232, 238, 240, 242, 245, 246, 250, 252, 256, 257,
- 258, 259, 267, 268, 271, 274, 275, 276, 284, 285,
- 291, 293, 297, 301, 305, 309, 313, 317, 321, 325,
- 329, 333, 337, 341, 345, 349, 353, 357, 361, 365,
- 369, 373, 375, 378, 381, 384, 387, 390, 393, 396,
- 399, 403, 409, 416, 418, 420, 424, 430, 436, 441,
- 448, 450, 455, 461, 467, 475, 477, 478, 482, 484,
- 489, 491, 495, 497, 499, 501, 503, 505, 507, 509,
- 510, 512, 514, 516, 518, 523, 525, 527, 529, 532,
- 534, 536, 538, 540, 542, 546, 548, 550, 552, 555,
- 557, 559, 561, 563, 567, 569, 571, 573, 575, 577,
- 579, 581, 583, 585, 589, 594, 599, 602, 606, 612,
- 614, 616, 619, 623, 629, 633, 639, 643, 647, 653,
- 662, 668, 677, 683, 684, 688, 689, 691, 695, 697,
- 702, 705, 706, 710, 712, 716, 718, 722, 724, 728,
- 730, 734, 736, 740, 744, 747, 752, 756, 762, 768,
- 770, 774, 776, 779, 781, 785, 790, 792, 795, 798,
- 800, 802, 806, 807, 810, 811, 813, 815, 817, 819,
- 821, 823, 825, 827, 829, 830, 835, 837, 840, 843,
- 846, 849, 852, 855, 857, 861, 863, 867, 869, 873,
- 875, 879, 881, 885, 887, 889, 893, 897, 898, 901,
- 902, 904, 905, 907, 908, 910, 911, 913, 914, 916,
- 917, 919, 920, 922, 923, 925, 926, 928, 933, 938,
- 944, 951, 956, 961, 963, 965, 967, 969, 971, 973,
- 975, 977, 979, 983, 988, 994, 999, 1004, 1007, 1010,
- 1015, 1019, 1023, 1029, 1033, 1038, 1042, 1048, 1050, 1051,
- 1053, 1057, 1059, 1061, 1064, 1066, 1068, 1074, 1075, 1078,
- 1080, 1084, 1086, 1090, 1092
+ 258, 259, 268, 269, 275, 276, 279, 280, 283, 284,
+ 285, 293, 294, 300, 302, 306, 310, 314, 318, 322,
+ 326, 330, 334, 338, 342, 346, 350, 354, 358, 362,
+ 366, 370, 374, 378, 382, 384, 387, 390, 393, 396,
+ 399, 402, 405, 408, 412, 418, 425, 427, 429, 433,
+ 439, 445, 450, 457, 459, 465, 471, 477, 485, 487,
+ 488, 492, 494, 499, 501, 506, 508, 512, 514, 516,
+ 518, 520, 522, 524, 526, 527, 529, 531, 533, 535,
+ 540, 542, 544, 546, 549, 551, 553, 555, 557, 559,
+ 563, 565, 567, 569, 572, 574, 576, 578, 580, 584,
+ 586, 588, 590, 592, 594, 596, 598, 600, 602, 606,
+ 611, 616, 619, 623, 629, 631, 633, 636, 640, 646,
+ 650, 656, 660, 664, 670, 679, 685, 694, 700, 701,
+ 705, 706, 708, 712, 714, 719, 722, 723, 727, 729,
+ 733, 735, 739, 741, 745, 747, 751, 753, 757, 761,
+ 764, 769, 773, 779, 785, 787, 791, 793, 796, 798,
+ 802, 807, 809, 812, 815, 817, 819, 823, 824, 827,
+ 828, 830, 832, 834, 836, 838, 840, 842, 844, 846,
+ 847, 852, 854, 857, 860, 863, 866, 869, 872, 874,
+ 878, 880, 884, 886, 890, 892, 896, 898, 902, 904,
+ 906, 910, 914, 915, 918, 919, 921, 922, 924, 925,
+ 927, 928, 930, 931, 933, 934, 936, 937, 939, 940,
+ 942, 943, 945, 950, 955, 961, 968, 973, 978, 980,
+ 982, 984, 986, 988, 990, 992, 994, 996, 1000, 1005,
+ 1011, 1016, 1021, 1024, 1027, 1032, 1036, 1040, 1046, 1050,
+ 1055, 1059, 1065, 1067, 1068, 1070, 1074, 1076, 1078, 1081,
+ 1083, 1085, 1091, 1092, 1095, 1097, 1101, 1103, 1107, 1109
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int16 yyrhs[] =
{
- 77, 0, -1, 79, 78, 81, 162, -1, -1, 25,
- 137, 62, -1, -1, 80, 86, 88, -1, -1, 81,
- 82, 62, -1, 21, 83, -1, 21, 59, 84, 186,
+ 77, 0, -1, 79, 78, 81, 166, -1, -1, 25,
+ 141, 62, -1, -1, 80, 86, 88, -1, -1, 81,
+ 82, 62, -1, 21, 83, -1, 21, 59, 84, 190,
60, -1, 21, 59, 60, -1, 85, 86, 88, -1,
85, 88, -1, 83, -1, 84, 62, 83, -1, 3,
- -1, 137, 3, -1, 63, 3, -1, 25, 24, 87,
- 62, -1, -1, 24, -1, -1, 89, 210, 64, 64,
- -1, -1, 91, -1, 154, -1, 177, -1, 1, -1,
- 32, 93, -1, 32, 59, 163, 186, 60, -1, 32,
- 59, 60, -1, 92, 94, -1, 92, 59, 94, 186,
- 60, -1, 92, 59, 94, 62, 164, 186, 60, -1,
- 92, 59, 60, -1, 31, 97, -1, 31, 59, 165,
- 186, 60, -1, 31, 59, 60, -1, 9, -1, 181,
- 142, -1, 181, 142, 65, 182, -1, 181, 65, 182,
- -1, 181, 142, 65, 182, -1, 181, 65, 182, -1,
- 94, -1, 181, 142, -1, 181, -1, 137, -1, 96,
- 142, -1, 123, -1, 123, 4, 123, -1, 182, 65,
- 182, -1, 182, 8, 182, -1, 123, 42, -1, 123,
- 37, -1, 6, 183, 66, -1, 6, 183, 65, 123,
- 66, -1, 6, 183, 8, 123, 66, -1, 12, 66,
- -1, -1, 67, 101, 179, 68, -1, -1, 99, 103,
- 179, -1, -1, 104, 102, -1, -1, 35, 106, 179,
- 68, -1, 182, 65, 26, 123, -1, 182, 8, 26,
- 123, -1, 190, 62, 190, 62, 190, -1, 190, -1,
+ -1, 141, 3, -1, 63, 3, -1, 25, 24, 87,
+ 62, -1, -1, 24, -1, -1, 89, 214, 64, 64,
+ -1, -1, 91, -1, 158, -1, 181, -1, 1, -1,
+ 32, 93, -1, 32, 59, 167, 190, 60, -1, 32,
+ 59, 60, -1, 92, 94, -1, 92, 59, 94, 190,
+ 60, -1, 92, 59, 94, 62, 168, 190, 60, -1,
+ 92, 59, 60, -1, 31, 97, -1, 31, 59, 169,
+ 190, 60, -1, 31, 59, 60, -1, 9, -1, 185,
+ 146, -1, 185, 146, 65, 186, -1, 185, 65, 186,
+ -1, 185, 146, 65, 186, -1, 185, 65, 186, -1,
+ 94, -1, 185, 146, -1, 185, -1, 141, -1, 96,
+ 146, -1, 126, -1, 126, 4, 126, -1, 186, 65,
+ 186, -1, 186, 5, 186, -1, 126, 42, -1, 126,
+ 37, -1, 7, 187, 66, -1, 7, 187, 65, 126,
+ 66, -1, 7, 187, 5, 126, 66, -1, 12, 66,
+ -1, -1, 67, 101, 183, 68, -1, -1, 99, 103,
+ 183, -1, -1, 104, 102, -1, -1, 35, 106, 183,
+ 68, -1, 186, 65, 26, 126, -1, 186, 5, 26,
+ 126, -1, 194, 62, 194, 62, 194, -1, 194, -1,
107, -1, 108, 105, -1, -1, 16, 111, 109, -1,
- 190, -1, 190, 62, 190, -1, -1, -1, -1, 20,
- 114, 112, 115, 105, 116, 117, -1, -1, 14, 113,
- -1, 14, 100, -1, -1, -1, 30, 119, 112, 120,
- 35, 104, 68, -1, -1, 28, 122, 35, 104, 68,
- -1, 124, -1, 123, 47, 123, -1, 123, 33, 123,
- -1, 123, 38, 123, -1, 123, 46, 123, -1, 123,
- 45, 123, -1, 123, 43, 123, -1, 123, 39, 123,
- -1, 123, 40, 123, -1, 123, 49, 123, -1, 123,
- 50, 123, -1, 123, 51, 123, -1, 123, 52, 123,
- -1, 123, 53, 123, -1, 123, 54, 123, -1, 123,
- 55, 123, -1, 123, 56, 123, -1, 123, 34, 123,
- -1, 123, 44, 123, -1, 123, 48, 123, -1, 123,
- 36, 123, -1, 130, -1, 53, 124, -1, 56, 124,
- -1, 49, 124, -1, 50, 124, -1, 69, 124, -1,
- 70, 124, -1, 52, 124, -1, 36, 124, -1, 130,
- 59, 60, -1, 130, 59, 183, 187, 60, -1, 130,
- 59, 183, 11, 187, 60, -1, 3, -1, 139, -1,
- 130, 63, 137, -1, 130, 63, 59, 131, 60, -1,
- 130, 63, 59, 31, 60, -1, 130, 71, 123, 72,
- -1, 130, 71, 188, 66, 188, 72, -1, 125, -1,
- 145, 59, 123, 60, -1, 146, 133, 127, 185, 68,
- -1, 126, 67, 127, 185, 68, -1, 59, 131, 60,
- 67, 127, 185, 68, -1, 161, -1, -1, 123, 66,
- 129, -1, 123, -1, 67, 127, 185, 68, -1, 126,
- -1, 59, 131, 60, -1, 123, -1, 143, -1, 142,
- -1, 35, -1, 67, -1, 137, -1, 137, -1, -1,
- 134, -1, 24, -1, 138, -1, 73, -1, 74, 3,
- 63, 24, -1, 137, -1, 134, -1, 11, -1, 11,
- 142, -1, 151, -1, 157, -1, 149, -1, 150, -1,
- 148, -1, 59, 142, 60, -1, 151, -1, 157, -1,
- 149, -1, 53, 143, -1, 157, -1, 149, -1, 150,
- -1, 148, -1, 59, 142, 60, -1, 157, -1, 149,
- -1, 149, -1, 151, -1, 157, -1, 149, -1, 150,
- -1, 148, -1, 139, -1, 139, 63, 137, -1, 71,
- 188, 72, 142, -1, 71, 11, 72, 142, -1, 7,
- 144, -1, 7, 36, 142, -1, 23, 71, 142, 72,
- 142, -1, 152, -1, 153, -1, 53, 142, -1, 36,
- 7, 142, -1, 29, 133, 166, 186, 68, -1, 29,
- 133, 68, -1, 22, 133, 167, 186, 68, -1, 22,
- 133, 68, -1, 17, 155, 158, -1, 137, 59, 175,
- 60, 159, -1, 59, 175, 60, 137, 59, 175, 60,
- 159, -1, 196, 59, 191, 60, 206, -1, 59, 211,
- 60, 137, 59, 191, 60, 206, -1, 17, 59, 175,
- 60, 159, -1, -1, 67, 179, 68, -1, -1, 147,
- -1, 59, 175, 60, -1, 157, -1, 160, 133, 179,
- 68, -1, 160, 1, -1, -1, 162, 90, 62, -1,
- 93, -1, 163, 62, 93, -1, 95, -1, 164, 62,
- 95, -1, 97, -1, 165, 62, 97, -1, 168, -1,
- 166, 62, 168, -1, 171, -1, 167, 62, 171, -1,
- 180, 142, 194, -1, 170, 194, -1, 59, 170, 60,
- 194, -1, 53, 170, 194, -1, 59, 53, 170, 60,
- 194, -1, 53, 59, 170, 60, 194, -1, 24, -1,
- 24, 63, 137, -1, 169, -1, 134, 172, -1, 169,
- -1, 59, 169, 60, -1, 59, 175, 60, 159, -1,
- 132, -1, 137, 132, -1, 137, 141, -1, 141, -1,
- 173, -1, 174, 75, 173, -1, -1, 174, 187, -1,
- -1, 100, -1, 91, -1, 177, -1, 1, -1, 98,
- -1, 110, -1, 118, -1, 121, -1, 113, -1, -1,
- 140, 66, 178, 176, -1, 15, -1, 5, 136, -1,
- 10, 136, -1, 18, 125, -1, 13, 125, -1, 19,
- 134, -1, 27, 189, -1, 176, -1, 179, 62, 176,
- -1, 134, -1, 180, 75, 134, -1, 135, -1, 181,
- 75, 135, -1, 123, -1, 182, 75, 123, -1, 131,
- -1, 183, 75, 131, -1, 128, -1, 129, -1, 184,
- 75, 128, -1, 184, 75, 129, -1, -1, 184, 187,
- -1, -1, 62, -1, -1, 75, -1, -1, 123, -1,
- -1, 182, -1, -1, 98, -1, -1, 211, -1, -1,
- 212, -1, -1, 213, -1, -1, 3, -1, 21, 24,
- 3, 62, -1, 32, 196, 198, 62, -1, 9, 196,
- 65, 209, 62, -1, 9, 196, 198, 65, 209, 62,
- -1, 31, 197, 198, 62, -1, 17, 156, 158, 62,
- -1, 138, -1, 196, -1, 200, -1, 201, -1, 202,
- -1, 200, -1, 202, -1, 138, -1, 24, -1, 71,
- 72, 198, -1, 71, 3, 72, 198, -1, 23, 71,
- 198, 72, 198, -1, 29, 67, 192, 68, -1, 22,
- 67, 193, 68, -1, 53, 198, -1, 7, 199, -1,
- 7, 59, 201, 60, -1, 7, 36, 198, -1, 36,
- 7, 198, -1, 17, 59, 191, 60, 206, -1, 137,
- 198, 194, -1, 137, 11, 198, 194, -1, 137, 198,
- 194, -1, 137, 59, 191, 60, 206, -1, 198, -1,
- -1, 207, -1, 59, 191, 60, -1, 198, -1, 3,
- -1, 50, 3, -1, 137, -1, 208, -1, 59, 208,
- 49, 208, 60, -1, -1, 210, 195, -1, 203, -1,
- 211, 75, 203, -1, 204, -1, 212, 62, 204, -1,
- 205, -1, 213, 62, 205, -1
+ 194, -1, 194, 62, 194, -1, -1, -1, -1, 20,
+ 114, 112, 115, 105, 116, 119, 120, -1, -1, 14,
+ 20, 118, 112, 105, -1, -1, 119, 117, -1, -1,
+ 14, 100, -1, -1, -1, 30, 122, 112, 123, 35,
+ 104, 68, -1, -1, 28, 125, 35, 104, 68, -1,
+ 127, -1, 126, 47, 126, -1, 126, 33, 126, -1,
+ 126, 38, 126, -1, 126, 46, 126, -1, 126, 45,
+ 126, -1, 126, 43, 126, -1, 126, 39, 126, -1,
+ 126, 40, 126, -1, 126, 49, 126, -1, 126, 50,
+ 126, -1, 126, 51, 126, -1, 126, 52, 126, -1,
+ 126, 53, 126, -1, 126, 54, 126, -1, 126, 55,
+ 126, -1, 126, 56, 126, -1, 126, 34, 126, -1,
+ 126, 44, 126, -1, 126, 48, 126, -1, 126, 36,
+ 126, -1, 134, -1, 53, 127, -1, 56, 127, -1,
+ 49, 127, -1, 50, 127, -1, 69, 127, -1, 70,
+ 127, -1, 52, 127, -1, 36, 127, -1, 134, 59,
+ 60, -1, 134, 59, 187, 191, 60, -1, 134, 59,
+ 187, 11, 191, 60, -1, 3, -1, 143, -1, 134,
+ 63, 141, -1, 134, 63, 59, 135, 60, -1, 134,
+ 63, 59, 31, 60, -1, 134, 71, 126, 72, -1,
+ 134, 71, 192, 66, 192, 72, -1, 128, -1, 149,
+ 59, 126, 191, 60, -1, 150, 137, 130, 189, 68,
+ -1, 129, 67, 130, 189, 68, -1, 59, 135, 60,
+ 67, 130, 189, 68, -1, 165, -1, -1, 126, 66,
+ 133, -1, 126, -1, 67, 130, 189, 68, -1, 126,
+ -1, 67, 130, 189, 68, -1, 129, -1, 59, 135,
+ 60, -1, 126, -1, 147, -1, 146, -1, 35, -1,
+ 67, -1, 141, -1, 141, -1, -1, 138, -1, 24,
+ -1, 142, -1, 73, -1, 74, 3, 63, 24, -1,
+ 141, -1, 138, -1, 11, -1, 11, 146, -1, 155,
+ -1, 161, -1, 153, -1, 154, -1, 152, -1, 59,
+ 146, 60, -1, 155, -1, 161, -1, 153, -1, 53,
+ 147, -1, 161, -1, 153, -1, 154, -1, 152, -1,
+ 59, 146, 60, -1, 161, -1, 153, -1, 153, -1,
+ 155, -1, 161, -1, 153, -1, 154, -1, 152, -1,
+ 143, -1, 143, 63, 141, -1, 71, 192, 72, 146,
+ -1, 71, 11, 72, 146, -1, 8, 148, -1, 8,
+ 36, 146, -1, 23, 71, 146, 72, 146, -1, 156,
+ -1, 157, -1, 53, 146, -1, 36, 8, 146, -1,
+ 29, 137, 170, 190, 68, -1, 29, 137, 68, -1,
+ 22, 137, 171, 190, 68, -1, 22, 137, 68, -1,
+ 17, 159, 162, -1, 141, 59, 179, 60, 163, -1,
+ 59, 179, 60, 141, 59, 179, 60, 163, -1, 200,
+ 59, 195, 60, 210, -1, 59, 215, 60, 141, 59,
+ 195, 60, 210, -1, 17, 59, 179, 60, 163, -1,
+ -1, 67, 183, 68, -1, -1, 151, -1, 59, 179,
+ 60, -1, 161, -1, 164, 137, 183, 68, -1, 164,
+ 1, -1, -1, 166, 90, 62, -1, 93, -1, 167,
+ 62, 93, -1, 95, -1, 168, 62, 95, -1, 97,
+ -1, 169, 62, 97, -1, 172, -1, 170, 62, 172,
+ -1, 175, -1, 171, 62, 175, -1, 184, 146, 198,
+ -1, 174, 198, -1, 59, 174, 60, 198, -1, 53,
+ 174, 198, -1, 59, 53, 174, 60, 198, -1, 53,
+ 59, 174, 60, 198, -1, 24, -1, 24, 63, 141,
+ -1, 173, -1, 138, 176, -1, 173, -1, 59, 173,
+ 60, -1, 59, 179, 60, 163, -1, 136, -1, 141,
+ 136, -1, 141, 145, -1, 145, -1, 177, -1, 178,
+ 75, 177, -1, -1, 178, 191, -1, -1, 100, -1,
+ 91, -1, 181, -1, 1, -1, 98, -1, 110, -1,
+ 121, -1, 124, -1, 113, -1, -1, 144, 66, 182,
+ 180, -1, 15, -1, 6, 140, -1, 10, 140, -1,
+ 18, 128, -1, 13, 128, -1, 19, 138, -1, 27,
+ 193, -1, 180, -1, 183, 62, 180, -1, 138, -1,
+ 184, 75, 138, -1, 139, -1, 185, 75, 139, -1,
+ 126, -1, 186, 75, 126, -1, 135, -1, 187, 75,
+ 135, -1, 131, -1, 132, -1, 188, 75, 131, -1,
+ 188, 75, 132, -1, -1, 188, 191, -1, -1, 62,
+ -1, -1, 75, -1, -1, 126, -1, -1, 186, -1,
+ -1, 98, -1, -1, 215, -1, -1, 216, -1, -1,
+ 217, -1, -1, 3, -1, 21, 24, 3, 62, -1,
+ 32, 200, 202, 62, -1, 9, 200, 65, 213, 62,
+ -1, 9, 200, 202, 65, 213, 62, -1, 31, 201,
+ 202, 62, -1, 17, 160, 162, 62, -1, 142, -1,
+ 200, -1, 204, -1, 205, -1, 206, -1, 204, -1,
+ 206, -1, 142, -1, 24, -1, 71, 72, 202, -1,
+ 71, 3, 72, 202, -1, 23, 71, 202, 72, 202,
+ -1, 29, 67, 196, 68, -1, 22, 67, 197, 68,
+ -1, 53, 202, -1, 8, 203, -1, 8, 59, 205,
+ 60, -1, 8, 36, 202, -1, 36, 8, 202, -1,
+ 17, 59, 195, 60, 210, -1, 141, 202, 198, -1,
+ 141, 11, 202, 198, -1, 141, 202, 198, -1, 141,
+ 59, 195, 60, 210, -1, 202, -1, -1, 211, -1,
+ 59, 195, 60, -1, 202, -1, 3, -1, 50, 3,
+ -1, 141, -1, 212, -1, 59, 212, 49, 212, 60,
+ -1, -1, 214, 199, -1, 207, -1, 215, 75, 207,
+ -1, 208, -1, 216, 62, 208, -1, 209, -1, 217,
+ 62, 209, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
@@ -676,36 +661,36 @@ static const yytype_uint16 yyrline[] =
259, 260, 267, 267, 280, 284, 285, 289, 294, 300,
304, 308, 312, 318, 324, 330, 335, 339, 343, 349,
355, 359, 363, 369, 373, 379, 380, 384, 390, 399,
- 405, 409, 414, 426, 442, 447, 454, 474, 492, 501,
- 520, 519, 531, 530, 561, 564, 571, 570, 581, 587,
- 596, 607, 613, 616, 624, 623, 634, 640, 652, 656,
- 661, 651, 673, 676, 680, 687, 691, 686, 709, 708,
- 724, 725, 729, 733, 737, 741, 745, 749, 753, 757,
- 761, 765, 769, 773, 777, 781, 785, 789, 793, 797,
- 802, 808, 809, 813, 824, 828, 832, 836, 841, 845,
- 855, 859, 864, 872, 876, 877, 888, 892, 896, 900,
- 904, 905, 911, 918, 924, 931, 934, 941, 947, 948,
- 955, 956, 974, 975, 978, 981, 985, 996, 1005, 1011,
- 1014, 1017, 1024, 1025, 1031, 1040, 1048, 1060, 1065, 1071,
- 1072, 1073, 1074, 1075, 1076, 1082, 1083, 1084, 1085, 1091,
- 1092, 1093, 1094, 1095, 1101, 1102, 1105, 1108, 1109, 1110,
- 1111, 1112, 1115, 1116, 1129, 1133, 1138, 1143, 1148, 1152,
- 1153, 1156, 1162, 1169, 1175, 1182, 1188, 1199, 1210, 1239,
- 1278, 1301, 1318, 1327, 1330, 1338, 1342, 1346, 1353, 1359,
- 1364, 1376, 1379, 1387, 1388, 1394, 1395, 1401, 1405, 1411,
- 1412, 1418, 1422, 1428, 1451, 1456, 1462, 1468, 1475, 1484,
- 1493, 1508, 1514, 1519, 1523, 1530, 1543, 1544, 1550, 1556,
- 1559, 1563, 1569, 1572, 1581, 1584, 1585, 1589, 1590, 1596,
- 1597, 1598, 1599, 1600, 1602, 1601, 1616, 1621, 1625, 1629,
- 1633, 1637, 1642, 1661, 1667, 1675, 1679, 1685, 1689, 1695,
- 1699, 1705, 1709, 1718, 1722, 1726, 1730, 1736, 1739, 1747,
- 1748, 1750, 1751, 1754, 1757, 1760, 1763, 1766, 1769, 1772,
- 1775, 1778, 1781, 1784, 1787, 1790, 1793, 1799, 1803, 1807,
- 1811, 1815, 1819, 1837, 1844, 1855, 1856, 1857, 1860, 1861,
- 1864, 1868, 1878, 1882, 1886, 1890, 1894, 1898, 1902, 1908,
- 1914, 1922, 1930, 1936, 1943, 1959, 1977, 1981, 1987, 1990,
- 1993, 1997, 2007, 2011, 2026, 2034, 2035, 2045, 2046, 2049,
- 2053, 2059, 2063, 2069, 2073
+ 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
};
#endif
@@ -714,8 +699,8 @@ static const yytype_uint16 yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
const char *yytname[] =
{
- "$end", "error", "$undefined", "LLITERAL", "LASOP", "LBREAK", "LCASE",
- "LCHAN", "LCOLAS", "LCONST", "LCONTINUE", "LDDD", "LDEFAULT", "LDEFER",
+ "$end", "error", "$undefined", "LLITERAL", "LASOP", "LCOLAS", "LBREAK",
+ "LCASE", "LCHAN", "LCONST", "LCONTINUE", "LDDD", "LDEFAULT", "LDEFER",
"LELSE", "LFALL", "LFOR", "LFUNC", "LGO", "LGOTO", "LIF", "LIMPORT",
"LINTERFACE", "LMAP", "LNAME", "LPACKAGE", "LRANGE", "LRETURN",
"LSELECT", "LSTRUCT", "LSWITCH", "LTYPE", "LVAR", "LANDAND", "LANDNOT",
@@ -724,30 +709,31 @@ const char *yytname[] =
"'/'", "'%'", "'&'", "NotPackage", "NotParen", "'('", "')'",
"PreferToRightParen", "';'", "'.'", "'$'", "'='", "':'", "'{'", "'}'",
"'!'", "'~'", "'['", "']'", "'?'", "'@'", "','", "$accept", "file",
- "package", "loadsys", "$@1", "imports", "import", "import_stmt",
+ "package", "loadsys", "@1", "imports", "import", "import_stmt",
"import_stmt_list", "import_here", "import_package", "import_safety",
- "import_there", "$@2", "xdcl", "common_dcl", "lconst", "vardcl",
+ "import_there", "@2", "xdcl", "common_dcl", "lconst", "vardcl",
"constdcl", "constdcl1", "typedclname", "typedcl", "simple_stmt", "case",
- "compound_stmt", "$@3", "caseblock", "$@4", "caseblock_list",
- "loop_body", "$@5", "range_stmt", "for_header", "for_body", "for_stmt",
- "$@6", "if_header", "if_stmt", "$@7", "$@8", "$@9", "else",
- "switch_stmt", "$@10", "$@11", "select_stmt", "$@12", "expr", "uexpr",
- "pseudocall", "pexpr_no_paren", "start_complit", "keyval", "complitexpr",
- "pexpr", "expr_or_type", "name_or_type", "lbrace", "new_name",
- "dcl_name", "onew_name", "sym", "hidden_importsym", "name", "labelname",
- "dotdotdot", "ntype", "non_expr_type", "non_recvchantype", "convtype",
- "comptype", "fnret_type", "dotname", "othertype", "ptrtype",
- "recvchantype", "structtype", "interfacetype", "xfndcl", "fndcl",
- "hidden_fndcl", "fntype", "fnbody", "fnres", "fnlitdcl", "fnliteral",
- "xdcl_list", "vardcl_list", "constdcl_list", "typedcl_list",
- "structdcl_list", "interfacedcl_list", "structdcl", "packname", "embed",
- "interfacedcl", "indcl", "arg_type", "arg_type_list",
- "oarg_type_list_ocomma", "stmt", "non_dcl_stmt", "$@13", "stmt_list",
- "new_name_list", "dcl_name_list", "expr_list", "expr_or_type_list",
- "keyval_list", "braced_keyval_list", "osemi", "ocomma", "oexpr",
- "oexpr_list", "osimple_stmt", "ohidden_funarg_list",
- "ohidden_structdcl_list", "ohidden_interfacedcl_list", "oliteral",
- "hidden_import", "hidden_pkg_importsym", "hidden_pkgtype", "hidden_type",
+ "compound_stmt", "@3", "caseblock", "@4", "caseblock_list", "loop_body",
+ "@5", "range_stmt", "for_header", "for_body", "for_stmt", "@6",
+ "if_header", "if_stmt", "@7", "@8", "@9", "elseif", "@10", "elseif_list",
+ "else", "switch_stmt", "@11", "@12", "select_stmt", "@13", "expr",
+ "uexpr", "pseudocall", "pexpr_no_paren", "start_complit", "keyval",
+ "bare_complitexpr", "complitexpr", "pexpr", "expr_or_type",
+ "name_or_type", "lbrace", "new_name", "dcl_name", "onew_name", "sym",
+ "hidden_importsym", "name", "labelname", "dotdotdot", "ntype",
+ "non_expr_type", "non_recvchantype", "convtype", "comptype",
+ "fnret_type", "dotname", "othertype", "ptrtype", "recvchantype",
+ "structtype", "interfacetype", "xfndcl", "fndcl", "hidden_fndcl",
+ "fntype", "fnbody", "fnres", "fnlitdcl", "fnliteral", "xdcl_list",
+ "vardcl_list", "constdcl_list", "typedcl_list", "structdcl_list",
+ "interfacedcl_list", "structdcl", "packname", "embed", "interfacedcl",
+ "indcl", "arg_type", "arg_type_list", "oarg_type_list_ocomma", "stmt",
+ "non_dcl_stmt", "@14", "stmt_list", "new_name_list", "dcl_name_list",
+ "expr_list", "expr_or_type_list", "keyval_list", "braced_keyval_list",
+ "osemi", "ocomma", "oexpr", "oexpr_list", "osimple_stmt",
+ "ohidden_funarg_list", "ohidden_structdcl_list",
+ "ohidden_interfacedcl_list", "oliteral", "hidden_import",
+ "hidden_pkg_importsym", "hidden_pkgtype", "hidden_type",
"hidden_type_non_recv_chan", "hidden_type_misc", "hidden_type_recv_chan",
"hidden_type_func", "hidden_funarg", "hidden_structdcl",
"hidden_interfacedcl", "ohidden_funres", "hidden_funres",
@@ -784,33 +770,33 @@ static const yytype_uint8 yyr1[] =
98, 98, 98, 98, 98, 98, 99, 99, 99, 99,
101, 100, 103, 102, 104, 104, 106, 105, 107, 107,
108, 108, 108, 109, 111, 110, 112, 112, 114, 115,
- 116, 113, 117, 117, 117, 119, 120, 118, 122, 121,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 125, 125, 125, 126, 126, 126, 126, 126, 126, 126,
- 126, 126, 126, 126, 126, 126, 127, 128, 129, 129,
- 130, 130, 131, 131, 132, 133, 133, 134, 135, 136,
- 136, 137, 137, 137, 138, 139, 140, 141, 141, 142,
- 142, 142, 142, 142, 142, 143, 143, 143, 143, 144,
- 144, 144, 144, 144, 145, 145, 146, 147, 147, 147,
- 147, 147, 148, 148, 149, 149, 149, 149, 149, 149,
- 149, 150, 151, 152, 152, 153, 153, 154, 155, 155,
- 156, 156, 157, 158, 158, 159, 159, 159, 160, 161,
- 161, 162, 162, 163, 163, 164, 164, 165, 165, 166,
- 166, 167, 167, 168, 168, 168, 168, 168, 168, 169,
- 169, 170, 171, 171, 171, 172, 173, 173, 173, 173,
- 174, 174, 175, 175, 176, 176, 176, 176, 176, 177,
- 177, 177, 177, 177, 178, 177, 177, 177, 177, 177,
- 177, 177, 177, 179, 179, 180, 180, 181, 181, 182,
- 182, 183, 183, 184, 184, 184, 184, 185, 185, 186,
- 186, 187, 187, 188, 188, 189, 189, 190, 190, 191,
- 191, 192, 192, 193, 193, 194, 194, 195, 195, 195,
- 195, 195, 195, 196, 197, 198, 198, 198, 199, 199,
- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
- 200, 201, 202, 203, 203, 204, 205, 205, 206, 206,
- 207, 207, 208, 208, 208, 209, 209, 210, 210, 211,
- 211, 212, 212, 213, 213
+ 116, 113, 118, 117, 119, 119, 120, 120, 122, 123,
+ 121, 125, 124, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 128, 128, 128, 129, 129, 129, 129,
+ 129, 129, 129, 129, 129, 129, 129, 129, 129, 130,
+ 131, 132, 132, 133, 133, 134, 134, 135, 135, 136,
+ 137, 137, 138, 139, 140, 140, 141, 141, 141, 142,
+ 143, 144, 145, 145, 146, 146, 146, 146, 146, 146,
+ 147, 147, 147, 147, 148, 148, 148, 148, 148, 149,
+ 149, 150, 151, 151, 151, 151, 151, 152, 152, 153,
+ 153, 153, 153, 153, 153, 153, 154, 155, 156, 156,
+ 157, 157, 158, 159, 159, 160, 160, 161, 162, 162,
+ 163, 163, 163, 164, 165, 165, 166, 166, 167, 167,
+ 168, 168, 169, 169, 170, 170, 171, 171, 172, 172,
+ 172, 172, 172, 172, 173, 173, 174, 175, 175, 175,
+ 176, 177, 177, 177, 177, 178, 178, 179, 179, 180,
+ 180, 180, 180, 180, 181, 181, 181, 181, 181, 182,
+ 181, 181, 181, 181, 181, 181, 181, 181, 183, 183,
+ 184, 184, 185, 185, 186, 186, 187, 187, 188, 188,
+ 188, 188, 189, 189, 190, 190, 191, 191, 192, 192,
+ 193, 193, 194, 194, 195, 195, 196, 196, 197, 197,
+ 198, 198, 199, 199, 199, 199, 199, 199, 200, 201,
+ 202, 202, 202, 203, 203, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 205, 206, 207, 207,
+ 208, 209, 209, 210, 210, 211, 211, 212, 212, 212,
+ 213, 213, 214, 214, 215, 215, 216, 216, 217, 217
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -824,663 +810,674 @@ static const yytype_uint8 yyr2[] =
1, 3, 3, 3, 2, 2, 3, 5, 5, 2,
0, 4, 0, 3, 0, 2, 0, 4, 4, 4,
5, 1, 1, 2, 0, 3, 1, 3, 0, 0,
- 0, 7, 0, 2, 2, 0, 0, 7, 0, 5,
- 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 0, 8, 0, 5, 0, 2, 0, 2, 0, 0,
+ 7, 0, 5, 1, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 1, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 5, 6, 1, 1, 3, 5, 5, 4, 6,
- 1, 4, 5, 5, 7, 1, 0, 3, 1, 4,
- 1, 3, 1, 1, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 1, 4, 1, 1, 1, 2, 1,
- 1, 1, 1, 1, 3, 1, 1, 1, 2, 1,
- 1, 1, 1, 3, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 3, 4, 4, 2, 3, 5, 1,
- 1, 2, 3, 5, 3, 5, 3, 3, 5, 8,
- 5, 8, 5, 0, 3, 0, 1, 3, 1, 4,
- 2, 0, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 3, 3, 2, 4, 3, 5, 5, 1,
- 3, 1, 2, 1, 3, 4, 1, 2, 2, 1,
- 1, 3, 0, 2, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 4, 1, 2, 2, 2,
- 2, 2, 2, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 3, 1, 1, 3, 3, 0, 2, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 4, 4, 5,
- 6, 4, 4, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 3, 4, 5, 4, 4, 2, 2, 4,
- 3, 3, 5, 3, 4, 3, 5, 1, 0, 1,
- 3, 1, 1, 2, 1, 1, 5, 0, 2, 1,
- 3, 1, 3, 1, 3
+ 3, 3, 3, 3, 1, 2, 2, 2, 2, 2,
+ 2, 2, 2, 3, 5, 6, 1, 1, 3, 5,
+ 5, 4, 6, 1, 5, 5, 5, 7, 1, 0,
+ 3, 1, 4, 1, 4, 1, 3, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 1, 1, 1, 4,
+ 1, 1, 1, 2, 1, 1, 1, 1, 1, 3,
+ 1, 1, 1, 2, 1, 1, 1, 1, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 4,
+ 4, 2, 3, 5, 1, 1, 2, 3, 5, 3,
+ 5, 3, 3, 5, 8, 5, 8, 5, 0, 3,
+ 0, 1, 3, 1, 4, 2, 0, 3, 1, 3,
+ 1, 3, 1, 3, 1, 3, 1, 3, 3, 2,
+ 4, 3, 5, 5, 1, 3, 1, 2, 1, 3,
+ 4, 1, 2, 2, 1, 1, 3, 0, 2, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 4, 1, 2, 2, 2, 2, 2, 2, 1, 3,
+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 1,
+ 3, 3, 0, 2, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 4, 4, 5, 6, 4, 4, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 4, 5,
+ 4, 4, 2, 2, 4, 3, 3, 5, 3, 4,
+ 3, 5, 1, 0, 1, 3, 1, 1, 2, 1,
+ 1, 5, 0, 2, 1, 3, 1, 3, 1, 3
};
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint16 yydefact[] =
{
- 5, 0, 3, 0, 1, 0, 7, 0, 22, 151,
- 153, 0, 0, 152, 211, 20, 6, 337, 0, 4,
+ 5, 0, 3, 0, 1, 0, 7, 0, 22, 156,
+ 158, 0, 0, 157, 216, 20, 6, 342, 0, 4,
0, 0, 0, 21, 0, 0, 0, 16, 0, 0,
- 9, 22, 0, 8, 28, 123, 149, 0, 39, 149,
- 0, 256, 74, 0, 0, 0, 78, 0, 0, 285,
- 88, 0, 85, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 283, 0, 25, 0, 249, 250,
- 253, 251, 252, 50, 90, 130, 140, 111, 156, 155,
- 124, 0, 0, 0, 176, 189, 190, 26, 208, 0,
- 135, 27, 0, 19, 0, 0, 0, 0, 0, 0,
- 338, 154, 11, 14, 279, 18, 22, 13, 17, 150,
- 257, 147, 0, 0, 0, 0, 155, 182, 186, 172,
- 170, 171, 169, 258, 130, 0, 287, 242, 0, 203,
- 130, 261, 287, 145, 146, 0, 0, 269, 286, 262,
- 0, 0, 287, 0, 0, 36, 48, 0, 29, 267,
- 148, 0, 119, 114, 115, 118, 112, 113, 0, 0,
- 142, 0, 143, 167, 165, 166, 116, 117, 0, 284,
- 0, 212, 0, 32, 0, 0, 0, 0, 0, 55,
+ 9, 22, 0, 8, 28, 126, 154, 0, 39, 154,
+ 0, 261, 74, 0, 0, 0, 78, 0, 0, 290,
+ 91, 0, 88, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 288, 0, 25, 0, 254, 255,
+ 258, 256, 257, 50, 93, 133, 145, 114, 161, 160,
+ 127, 0, 0, 0, 181, 194, 195, 26, 213, 0,
+ 138, 27, 0, 19, 0, 0, 0, 0, 0, 0,
+ 343, 159, 11, 14, 284, 18, 22, 13, 17, 155,
+ 262, 152, 0, 0, 0, 0, 160, 187, 191, 177,
+ 175, 176, 174, 263, 133, 0, 292, 247, 0, 208,
+ 133, 266, 292, 150, 151, 0, 0, 274, 291, 267,
+ 0, 0, 292, 0, 0, 36, 48, 0, 29, 272,
+ 153, 0, 122, 117, 118, 121, 115, 116, 0, 0,
+ 147, 0, 148, 172, 170, 171, 119, 120, 0, 289,
+ 0, 217, 0, 32, 0, 0, 0, 0, 0, 55,
0, 0, 0, 54, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 136, 0,
- 0, 283, 254, 0, 136, 210, 0, 0, 0, 0,
- 303, 0, 0, 203, 0, 0, 304, 0, 0, 23,
- 280, 0, 12, 242, 0, 0, 187, 163, 161, 162,
- 159, 160, 191, 0, 0, 288, 72, 0, 75, 0,
- 71, 157, 236, 155, 239, 144, 240, 281, 0, 242,
- 0, 197, 79, 76, 151, 0, 196, 0, 279, 233,
- 221, 0, 64, 0, 0, 194, 265, 279, 219, 231,
- 295, 0, 86, 38, 217, 279, 49, 31, 213, 279,
- 0, 0, 40, 0, 168, 141, 0, 0, 35, 279,
- 0, 0, 51, 92, 107, 110, 93, 97, 98, 96,
- 108, 95, 94, 91, 109, 99, 100, 101, 102, 103,
- 104, 105, 106, 277, 120, 271, 281, 0, 125, 284,
- 0, 0, 0, 277, 248, 60, 246, 245, 263, 247,
- 0, 53, 52, 270, 0, 0, 0, 0, 311, 0,
- 0, 0, 0, 0, 310, 0, 305, 306, 307, 0,
- 339, 0, 0, 289, 0, 0, 0, 15, 10, 0,
- 0, 0, 173, 183, 66, 73, 0, 0, 287, 158,
- 237, 238, 282, 243, 205, 0, 0, 0, 287, 0,
- 229, 0, 242, 232, 280, 0, 0, 0, 0, 295,
- 0, 0, 280, 0, 296, 224, 0, 295, 0, 280,
- 0, 280, 0, 42, 268, 0, 0, 0, 192, 163,
- 161, 162, 160, 136, 185, 184, 280, 0, 44, 0,
- 136, 138, 273, 274, 281, 0, 281, 282, 0, 0,
- 0, 128, 283, 255, 131, 0, 0, 0, 209, 0,
- 0, 318, 308, 309, 289, 293, 0, 291, 0, 317,
- 332, 0, 0, 334, 335, 0, 0, 0, 0, 0,
- 295, 0, 0, 302, 0, 290, 297, 301, 298, 205,
- 164, 0, 0, 0, 0, 241, 242, 155, 206, 181,
- 179, 180, 177, 178, 202, 205, 204, 80, 77, 230,
- 234, 0, 222, 195, 188, 0, 0, 89, 62, 65,
- 0, 226, 0, 295, 220, 193, 266, 223, 64, 218,
- 37, 214, 30, 41, 0, 277, 45, 215, 279, 47,
- 33, 43, 277, 0, 282, 278, 133, 282, 0, 272,
- 121, 127, 126, 0, 132, 0, 264, 320, 0, 0,
- 311, 0, 310, 0, 327, 343, 294, 0, 0, 0,
- 341, 292, 321, 333, 0, 299, 0, 312, 0, 295,
- 323, 0, 340, 328, 0, 69, 68, 287, 0, 242,
- 198, 82, 205, 0, 59, 0, 295, 295, 225, 0,
- 164, 0, 280, 0, 46, 0, 138, 137, 275, 276,
- 122, 129, 61, 319, 328, 289, 316, 0, 0, 295,
- 315, 0, 0, 313, 300, 324, 289, 289, 331, 200,
- 329, 67, 70, 207, 0, 0, 81, 235, 0, 0,
- 56, 0, 63, 228, 227, 87, 134, 216, 34, 139,
- 322, 0, 344, 314, 325, 342, 0, 0, 0, 205,
- 84, 83, 0, 0, 328, 336, 328, 330, 199, 58,
- 57, 326, 201
+ 0, 0, 0, 0, 0, 0, 0, 0, 139, 0,
+ 0, 288, 259, 0, 139, 215, 0, 0, 0, 0,
+ 308, 0, 0, 208, 0, 0, 309, 0, 0, 23,
+ 285, 0, 12, 247, 0, 0, 192, 168, 166, 167,
+ 164, 165, 196, 0, 0, 293, 72, 0, 75, 0,
+ 71, 162, 241, 160, 244, 149, 245, 286, 0, 247,
+ 0, 202, 79, 76, 156, 0, 201, 0, 284, 238,
+ 226, 0, 64, 0, 0, 199, 270, 284, 224, 236,
+ 300, 0, 89, 38, 222, 284, 49, 31, 218, 284,
+ 0, 0, 40, 0, 173, 146, 0, 0, 35, 284,
+ 0, 0, 51, 95, 110, 113, 96, 100, 101, 99,
+ 111, 98, 97, 94, 112, 102, 103, 104, 105, 106,
+ 107, 108, 109, 282, 123, 276, 286, 0, 128, 289,
+ 0, 0, 286, 282, 253, 60, 251, 250, 268, 252,
+ 0, 53, 52, 275, 0, 0, 0, 0, 316, 0,
+ 0, 0, 0, 0, 315, 0, 310, 311, 312, 0,
+ 344, 0, 0, 294, 0, 0, 0, 15, 10, 0,
+ 0, 0, 178, 188, 66, 73, 0, 0, 292, 163,
+ 242, 243, 287, 248, 210, 0, 0, 0, 292, 0,
+ 234, 0, 247, 237, 285, 0, 0, 0, 0, 300,
+ 0, 0, 285, 0, 301, 229, 0, 300, 0, 285,
+ 0, 285, 0, 42, 273, 0, 0, 0, 197, 168,
+ 166, 167, 165, 139, 190, 189, 285, 0, 44, 0,
+ 139, 141, 278, 279, 286, 0, 286, 287, 0, 0,
+ 0, 131, 288, 260, 287, 0, 0, 0, 0, 214,
+ 0, 0, 323, 313, 314, 294, 298, 0, 296, 0,
+ 322, 337, 0, 0, 339, 340, 0, 0, 0, 0,
+ 0, 300, 0, 0, 307, 0, 295, 302, 306, 303,
+ 210, 169, 0, 0, 0, 0, 246, 247, 160, 211,
+ 186, 184, 185, 182, 183, 207, 210, 209, 80, 77,
+ 235, 239, 0, 227, 200, 193, 0, 0, 92, 62,
+ 65, 0, 231, 0, 300, 225, 198, 271, 228, 64,
+ 223, 37, 219, 30, 41, 0, 282, 45, 220, 284,
+ 47, 33, 43, 282, 0, 287, 283, 136, 0, 277,
+ 124, 130, 129, 0, 134, 135, 0, 269, 325, 0,
+ 0, 316, 0, 315, 0, 332, 348, 299, 0, 0,
+ 0, 346, 297, 326, 338, 0, 304, 0, 317, 0,
+ 300, 328, 0, 345, 333, 0, 69, 68, 292, 0,
+ 247, 203, 84, 210, 0, 59, 0, 300, 300, 230,
+ 0, 169, 0, 285, 0, 46, 0, 139, 143, 140,
+ 280, 281, 125, 132, 61, 324, 333, 294, 321, 0,
+ 0, 300, 320, 0, 0, 318, 305, 329, 294, 294,
+ 336, 205, 334, 67, 70, 212, 0, 86, 240, 0,
+ 0, 56, 0, 63, 233, 232, 90, 137, 221, 34,
+ 142, 282, 327, 0, 349, 319, 330, 347, 0, 0,
+ 0, 210, 0, 85, 81, 0, 0, 0, 333, 341,
+ 333, 335, 204, 82, 87, 58, 57, 144, 331, 206,
+ 292, 0, 83
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
-1, 1, 6, 2, 3, 14, 21, 30, 104, 31,
- 8, 24, 16, 17, 65, 326, 67, 148, 516, 517,
- 144, 145, 68, 498, 327, 436, 499, 575, 387, 365,
- 471, 236, 237, 238, 69, 126, 252, 70, 132, 377,
- 571, 616, 71, 142, 398, 72, 140, 73, 74, 75,
- 76, 313, 422, 423, 77, 315, 242, 135, 78, 149,
- 110, 116, 13, 80, 81, 244, 245, 162, 118, 82,
- 83, 478, 227, 84, 229, 230, 85, 86, 87, 129,
- 213, 88, 251, 484, 89, 90, 22, 279, 518, 275,
- 267, 258, 268, 269, 270, 260, 383, 246, 247, 248,
- 328, 329, 321, 330, 271, 151, 92, 316, 424, 425,
- 221, 373, 170, 139, 253, 464, 549, 543, 395, 100,
- 211, 217, 608, 441, 346, 347, 348, 350, 550, 545,
- 609, 610, 454, 455, 25, 465, 551, 546
+ 8, 24, 16, 17, 65, 326, 67, 148, 517, 518,
+ 144, 145, 68, 499, 327, 437, 500, 576, 387, 365,
+ 472, 236, 237, 238, 69, 126, 252, 70, 132, 377,
+ 572, 643, 660, 617, 644, 71, 142, 398, 72, 140,
+ 73, 74, 75, 76, 313, 422, 423, 589, 77, 315,
+ 242, 135, 78, 149, 110, 116, 13, 80, 81, 244,
+ 245, 162, 118, 82, 83, 479, 227, 84, 229, 230,
+ 85, 86, 87, 129, 213, 88, 251, 485, 89, 90,
+ 22, 279, 519, 275, 267, 258, 268, 269, 270, 260,
+ 383, 246, 247, 248, 328, 329, 321, 330, 271, 151,
+ 92, 316, 424, 425, 221, 373, 170, 139, 253, 465,
+ 550, 544, 395, 100, 211, 217, 610, 442, 346, 347,
+ 348, 350, 551, 546, 611, 612, 455, 456, 25, 466,
+ 552, 547
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -551
+#define YYPACT_NINF -485
static const yytype_int16 yypact[] =
{
- -551, 46, 48, 121, -551, 58, -551, 135, -551, -551,
- -551, 65, 72, -551, 147, 156, -551, -551, 112, -551,
- 50, 134, 904, -551, 162, 463, 209, -551, 54, 237,
- -551, 121, 245, -551, -551, -551, 58, 1666, -551, 58,
- 288, -551, -551, 34, 288, 58, -551, 36, 184, 1467,
- -551, 36, -551, 316, 462, 1467, 1467, 1467, 1467, 1467,
- 1467, 1522, 1467, 1467, 965, 198, -551, 506, -551, -551,
- -551, -551, -551, 796, -551, -551, 195, 1, -551, 199,
- -551, 207, 216, 36, 221, -551, -551, -551, 226, 53,
- -551, -551, 108, -551, 214, 110, 269, 214, 214, 233,
- -551, -551, -551, -551, 238, -551, -551, -551, -551, -551,
- -551, -551, 242, 1691, 1691, 1691, -551, 240, -551, -551,
- -551, -551, -551, -551, 154, 1, 1467, 1658, 247, 246,
- 290, -551, 1467, -551, -551, 419, 1691, 2004, 229, -551,
- 272, 333, 1467, 258, 1691, -551, -551, 485, -551, -551,
- -551, 656, -551, -551, -551, -551, -551, -551, 1577, 1522,
- 2004, 255, -551, 10, -551, 51, -551, -551, 251, 2004,
- 256, -551, 508, -551, 1632, 1467, 1467, 1467, 1467, -551,
- 1467, 1467, 1467, -551, 1467, 1467, 1467, 1467, 1467, 1467,
- 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, -551, 1192,
- 552, 1467, -551, 1467, -551, -551, 1134, 1467, 1467, 1467,
- -551, 1203, 58, 246, 260, 332, -551, 1838, 1838, -551,
- 76, 282, -551, 1658, 344, 1691, -551, -551, -551, -551,
- -551, -551, -551, 293, 58, -551, -551, 328, -551, 178,
- 303, 1691, -551, 1658, -551, -551, -551, 295, 308, 1658,
- 1134, -551, -551, 309, 271, 364, -551, 334, 337, -551,
- -551, 330, -551, 11, 66, -551, -551, 342, -551, -551,
- 397, 664, -551, -551, -551, 351, -551, -551, -551, 352,
- 1467, 58, 343, 1719, -551, 349, 1691, 1691, -551, 356,
- 1467, 357, 2004, 2075, -551, 2028, 692, 692, 692, 692,
- -551, 692, 692, 2052, -551, 593, 593, 593, 593, -551,
- -551, -551, -551, 1247, -551, -551, 22, 1302, -551, 1877,
- 355, 1060, 1979, 1247, -551, -551, -551, -551, -551, -551,
- 86, 229, 229, 2004, 1777, 367, 361, 359, -551, 366,
- 427, 1838, 52, 29, -551, 370, -551, -551, -551, 784,
- -551, 118, 379, 58, 396, 400, 401, -551, -551, 404,
- 1691, 409, -551, -551, -551, -551, 1357, 1412, 1467, -551,
- -551, -551, 1658, -551, 1744, 414, 109, 328, 1467, 58,
- 416, 423, 1658, -551, 561, 417, 1691, 44, 364, 397,
- 364, 428, 451, 421, -551, -551, 58, 397, 456, 58,
- 436, 58, 438, 229, -551, 1467, 1752, 1691, -551, 24,
- 171, 287, 338, -551, -551, -551, 58, 439, 229, 1467,
- -551, 1907, -551, -551, 425, 435, 430, 1522, 446, 448,
- 453, -551, 1467, -551, -551, 443, 1134, 1060, -551, 1838,
- 479, -551, -551, -551, 58, 1805, 1838, 58, 1838, -551,
- -551, 514, 161, -551, -551, 460, 454, 1838, 52, 1838,
- 397, 58, 58, -551, 458, 459, -551, -551, -551, 1744,
- -551, 1134, 1467, 1467, 467, -551, 1658, 472, -551, -551,
- -551, -551, -551, -551, -551, 1744, -551, -551, -551, -551,
- -551, 477, -551, -551, -551, 1522, 474, -551, -551, -551,
- 482, -551, 500, 397, -551, -551, -551, -551, -551, -551,
- -551, -551, -551, 229, 501, 1247, -551, -551, 505, 1632,
- -551, 229, 1247, 1247, 1247, -551, -551, -551, 503, -551,
- -551, -551, -551, 511, -551, 137, -551, -551, 518, 528,
- 532, 534, 535, 530, -551, -551, 537, 533, 1838, 536,
- -551, 538, -551, -551, 560, -551, 1838, -551, 551, 397,
- -551, 557, -551, 1830, 151, 2004, 2004, 1467, 558, 1658,
- -551, 605, 1744, 125, -551, 1060, 397, 397, -551, 75,
- 360, 554, 58, 563, 357, 556, 2004, -551, -551, -551,
- -551, -551, -551, -551, 1830, 58, -551, 1805, 1838, 397,
- -551, 58, 161, -551, -551, -551, 58, 58, -551, -551,
- -551, -551, -551, -551, 570, 78, -551, -551, 1467, 1467,
- -551, 1522, 569, -551, -551, -551, -551, -551, -551, -551,
- -551, 576, -551, -551, -551, -551, 578, 582, 584, 1744,
- -551, -551, 1931, 1955, 1830, -551, 1830, -551, -551, -551,
- -551, -551, -551
+ -485, 67, 35, 55, -485, 44, -485, 64, -485, -485,
+ -485, 96, 38, -485, 77, 85, -485, -485, 66, -485,
+ 34, 84, 1059, -485, 86, 294, 147, -485, 165, 210,
+ -485, 55, 221, -485, -485, -485, 44, 1762, -485, 44,
+ 290, -485, -485, 442, 290, 44, -485, 80, 69, 1608,
+ -485, 80, -485, 450, 452, 1608, 1608, 1608, 1608, 1608,
+ 1608, 1651, 1608, 1608, 920, 157, -485, 460, -485, -485,
+ -485, -485, -485, 718, -485, -485, 167, 344, -485, 176,
+ -485, 180, 193, 80, 206, -485, -485, -485, 218, 91,
+ -485, -485, 76, -485, 205, 10, 260, 205, 205, 223,
+ -485, -485, -485, -485, 230, -485, -485, -485, -485, -485,
+ -485, -485, 237, 1770, 1770, 1770, -485, 236, -485, -485,
+ -485, -485, -485, -485, 220, 344, 1608, 990, 241, 235,
+ 262, -485, 1608, -485, -485, 405, 1770, 2090, 254, -485,
+ 297, 444, 1608, 61, 1770, -485, -485, 271, -485, -485,
+ -485, 671, -485, -485, -485, -485, -485, -485, 1694, 1651,
+ 2090, 291, -485, 181, -485, 60, -485, -485, 287, 2090,
+ 301, -485, 496, -485, 912, 1608, 1608, 1608, 1608, -485,
+ 1608, 1608, 1608, -485, 1608, 1608, 1608, 1608, 1608, 1608,
+ 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, -485, 1290,
+ 468, 1608, -485, 1608, -485, -485, 1221, 1608, 1608, 1608,
+ -485, 573, 44, 235, 275, 347, -485, 1301, 1301, -485,
+ 113, 302, -485, 990, 358, 1770, -485, -485, -485, -485,
+ -485, -485, -485, 316, 44, -485, -485, 340, -485, 78,
+ 318, 1770, -485, 990, -485, -485, -485, 307, 325, 990,
+ 1221, -485, -485, 324, 117, 365, -485, 343, 337, -485,
+ -485, 333, -485, 32, 23, -485, -485, 350, -485, -485,
+ 406, 1737, -485, -485, -485, 351, -485, -485, -485, 352,
+ 1608, 44, 354, 1796, -485, 353, 1770, 1770, -485, 359,
+ 1608, 357, 2090, 1928, -485, 2114, 1212, 1212, 1212, 1212,
+ -485, 1212, 1212, 2138, -485, 566, 566, 566, 566, -485,
+ -485, -485, -485, 1345, -485, -485, 31, 1400, -485, 1988,
+ 360, 1147, 1955, 1345, -485, -485, -485, -485, -485, -485,
+ 95, 254, 254, 2090, 1857, 368, 361, 371, -485, 363,
+ 427, 1301, 247, 51, -485, 374, -485, -485, -485, 1890,
+ -485, 36, 382, 44, 384, 385, 387, -485, -485, 391,
+ 1770, 395, -485, -485, -485, -485, 1455, 1510, 1608, -485,
+ -485, -485, 990, -485, 1823, 399, 135, 340, 1608, 44,
+ 397, 403, 990, -485, 542, 407, 1770, 278, 365, 406,
+ 365, 411, 364, 413, -485, -485, 44, 406, 430, 44,
+ 423, 44, 425, 254, -485, 1608, 1849, 1770, -485, 216,
+ 219, 274, 288, -485, -485, -485, 44, 426, 254, 1608,
+ -485, 2018, -485, -485, 414, 422, 416, 1651, 433, 434,
+ 436, -485, 1608, -485, -485, 439, 437, 1221, 1147, -485,
+ 1301, 466, -485, -485, -485, 44, 1882, 1301, 44, 1301,
+ -485, -485, 504, 207, -485, -485, 446, 438, 1301, 247,
+ 1301, 406, 44, 44, -485, 453, 455, -485, -485, -485,
+ 1823, -485, 1221, 1608, 1608, 467, -485, 990, 472, -485,
+ -485, -485, -485, -485, -485, -485, 1823, -485, -485, -485,
+ -485, -485, 475, -485, -485, -485, 1651, 470, -485, -485,
+ -485, 490, -485, 493, 406, -485, -485, -485, -485, -485,
+ -485, -485, -485, -485, 254, 495, 1345, -485, -485, 498,
+ 912, -485, 254, 1345, 1553, 1345, -485, -485, 497, -485,
+ -485, -485, -485, 486, -485, -485, 143, -485, -485, 501,
+ 502, 473, 508, 513, 505, -485, -485, 515, 503, 1301,
+ 511, -485, 518, -485, -485, 533, -485, 1301, -485, 522,
+ 406, -485, 526, -485, 1916, 144, 2090, 2090, 1608, 527,
+ 990, -485, -485, 1823, 39, -485, 1147, 406, 406, -485,
+ 315, 293, 521, 44, 548, 357, 525, -485, 2090, -485,
+ -485, -485, -485, -485, -485, -485, 1916, 44, -485, 1882,
+ 1301, 406, -485, 44, 207, -485, -485, -485, 44, 44,
+ -485, -485, -485, -485, -485, -485, 551, 572, -485, 1608,
+ 1608, -485, 1651, 550, -485, -485, -485, -485, -485, -485,
+ -485, 1345, -485, 558, -485, -485, -485, -485, 563, 564,
+ 565, 1823, 46, -485, -485, 2042, 2066, 559, 1916, -485,
+ 1916, -485, -485, -485, -485, -485, -485, -485, -485, -485,
+ 1608, 340, -485
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -551, -551, -551, -551, -551, -551, -551, -6, -551, -551,
- 608, -551, -11, -551, -551, 623, -551, -134, -25, 68,
- -551, -135, -121, -551, 39, -551, -551, -551, 145, 278,
- -551, -551, -551, -551, -551, -551, 515, 41, -551, -551,
- -551, -551, -551, -551, -551, -551, -551, 579, 493, 45,
- -551, -192, 138, -246, 192, -47, 415, 200, -20, 380,
- 626, -5, 449, 346, -551, 426, 95, 509, -551, -551,
- -551, -551, -33, 38, -31, -18, -551, -551, -551, -551,
- -551, 43, 457, -467, -551, -551, -551, -551, -551, -551,
- -551, -551, 280, -126, -227, 292, -551, 302, -551, -220,
- -297, 662, -551, -248, -551, -66, 18, 194, -551, -295,
- -228, -289, -191, -551, -119, -403, -551, -551, -305, -551,
- -32, -551, 127, -551, 362, 250, 363, 232, 90, 98,
- -550, -551, -426, 241, -551, 486, -551, -551
+ -485, -485, -485, -485, -485, -485, -485, -6, -485, -485,
+ 597, -485, -3, -485, -485, 608, -485, -131, -28, 50,
+ -485, -135, -106, -485, -7, -485, -485, -485, 125, -370,
+ -485, -485, -485, -485, -485, -485, -138, -485, -485, -485,
+ -485, -485, -485, -485, -485, -485, -485, -485, -485, -485,
+ 665, 15, 116, -485, -190, 111, 112, -485, 164, -59,
+ 398, 137, 14, 367, 603, -5, 454, 432, -485, 402,
+ -50, 491, -485, -485, -485, -485, -36, 18, -34, -9,
+ -485, -485, -485, -485, -485, 257, 441, -445, -485, -485,
+ -485, -485, -485, -485, -485, -485, 259, -116, -218, 265,
+ -485, 284, -485, -217, -286, 636, -485, -237, -485, -62,
+ -24, 166, -485, -314, -246, -265, -177, -485, -115, -415,
+ -485, -485, -379, -485, -8, -485, 435, -485, 326, 225,
+ 327, 204, 65, 70, -484, -485, -426, 211, -485, 462,
+ -485, -485
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
- number is the opposite. If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -270
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -275
static const yytype_int16 yytable[] =
{
- 12, 174, 376, 359, 119, 235, 121, 240, 274, 259,
- 320, 235, 323, 278, 161, 32, 109, 79, 570, 109,
- 107, 235, 103, 32, 433, 131, 554, 428, 435, 375,
- 385, 111, 456, 426, 111, 380, 389, 391, 128, 393,
- 111, 539, 173, 164, 630, -176, 4, 400, 146, 150,
- 495, 402, -208, 27, 205, 450, 496, 27, 9, -172,
- 199, 417, 150, 214, 200, 216, 218, 138, 18, -175,
- 388, 133, 201, 5, 9, 120, 9, -176, 9, 27,
- 122, 495, 9, -172, 501, 124, -208, 496, 133, 130,
- 380, -172, 507, 127, 651, 222, 652, 427, 46, 163,
- 9, 457, 451, 134, 165, 617, 174, 10, 11, 28,
- -174, 452, 497, 29, 102, 257, 207, 29, -208, 390,
- 134, 266, 243, 10, 11, 10, 11, 10, 11, 381,
- 111, 10, 11, 618, 19, 525, 111, 528, 146, 29,
- 536, 164, 150, 625, 239, 325, 7, 289, 437, 10,
- 11, 228, 228, 228, 438, 560, 231, 231, 231, 15,
- -260, 500, 491, 502, 450, 228, -260, 150, 20, 212,
- 231, 437, 648, 208, 228, 26, 636, 486, 461, 231,
- 23, 164, 228, 209, 11, 9, 366, 231, 535, 228,
- 619, 620, 631, 462, 231, 318, 33, 163, 578, 437,
- 621, 79, 165, 637, 638, 592, -170, 349, 226, 232,
- 233, 451, 228, 437, 357, 32, -260, 231, 243, 611,
- 581, 515, -260, 564, 93, 331, 332, 585, 522, 363,
- -170, 261, 125, 101, 10, 11, 125, 163, -170, 276,
- 105, 533, 165, 367, 243, 79, 282, 235, 108, 474,
- 409, 141, 411, 209, 605, 136, 568, 235, 259, 488,
- 171, 228, 198, 228, 509, -147, 231, 511, 231, 291,
- 430, 623, 624, 202, -229, 203, 150, 587, 589, 228,
- -175, 228, 9, 204, 231, -174, 231, 228, 11, 206,
- 583, 35, 231, 215, 634, 37, -259, 219, 403, 164,
- 220, 223, -259, 234, 209, 112, 249, 262, 418, 228,
- 47, 48, 9, 250, 231, 285, 79, 51, 273, 353,
- 361, 410, -171, 286, 228, 228, 412, 622, 287, 231,
- 231, 10, 11, -229, 379, 354, 369, 453, 345, -229,
- 9, 479, 358, 481, 355, 356, -171, 61, 349, 614,
- 519, 360, -259, 362, -171, 163, 482, 254, -259, 64,
- 165, 10, 11, 364, 257, 368, 397, 243, 374, 477,
- 372, 378, 266, -169, 489, 143, 506, 243, 408, 111,
- 529, 414, 415, 117, 331, 332, 263, 111, 380, 10,
- 11, 111, 264, 382, 146, -173, 150, -169, 228, 384,
- 394, 265, 386, 231, 392, -169, 10, 11, 405, 164,
- 228, 150, 480, 399, 401, 231, 413, 483, 416, -173,
- 228, 432, 419, 513, 228, 231, 444, -173, 445, 231,
- 446, 79, 79, 447, 448, 458, 479, 521, 481, 349,
- 541, 463, 548, 254, 228, 228, 235, 453, 612, 231,
- 231, 482, 479, 453, 481, 408, 561, 349, 466, 117,
- 117, 117, 467, 468, 469, 163, 79, 482, 449, 470,
- 165, 243, 94, 117, 485, 254, 460, 164, 255, 379,
- 95, 494, 117, 490, 96, 493, 9, 256, 503, 505,
- 117, 508, 10, 11, 97, 98, 510, 117, 512, 520,
- 524, 226, 514, 526, 263, 527, 530, 480, 531, 9,
- 264, 534, 483, 532, 228, 340, 519, 553, 563, 231,
- 117, 147, 555, 480, 10, 11, 556, 99, 483, 567,
- 9, 569, 9, 163, 462, 10, 11, 572, 165, 479,
- 574, 481, 576, 210, 210, 277, 210, 210, 152, 153,
- 154, 155, 156, 157, 482, 166, 167, 228, 10, 11,
- 577, 580, 231, 590, 243, 172, 537, 582, 288, 117,
- 79, 117, 544, 547, 529, 552, 9, 150, 593, 10,
- 11, 10, 11, 591, 557, 254, 559, 117, 594, 117,
- 349, -151, 541, 595, -152, 117, 548, 453, 596, 597,
- 601, 349, 349, 164, 600, 598, 479, 228, 481, 602,
- 480, 317, 231, 604, 584, 483, 606, 117, 613, 615,
- 255, 482, 626, 628, 629, 10, 11, 177, 137, 117,
- 639, 437, 117, 117, 10, 11, 644, 185, 645, 106,
- 160, 189, 646, 169, 647, 66, 194, 195, 196, 197,
- 627, 152, 156, 579, 640, 487, 641, 272, 370, 163,
- 344, 404, 588, 37, 165, 123, 344, 344, 284, 371,
- 352, 37, 504, 112, 475, 599, 492, 480, 47, 48,
- 9, 112, 483, 603, 91, 51, 47, 48, 9, 573,
- 538, 635, 224, 51, 562, 632, 442, 443, 351, 558,
- 224, 0, 0, 0, 0, 0, 117, 0, 0, 114,
- 0, 0, 0, 0, 0, 225, 0, 114, 117, 0,
- 117, 280, 0, 225, 544, 633, 177, 64, 117, 10,
- 11, 281, 117, 0, 0, 64, 185, 10, 11, 396,
+ 12, 119, 161, 121, 272, 174, 359, 488, 274, 436,
+ 502, 240, 385, 376, 323, 32, 278, 79, 508, 259,
+ 235, 393, 103, 32, 320, 138, 235, 555, 107, 400,
+ 540, 111, 375, 402, 111, 433, 235, 27, 128, 173,
+ 111, 571, 426, 417, 619, 389, 391, 380, 146, 150,
+ 109, 428, 164, 109, 457, 120, 380, 435, 9, 131,
+ 5, -213, 150, 226, 232, 233, 653, 4, 9, 212,
+ 152, 153, 154, 155, 156, 157, 390, 166, 167, 163,
+ 7, 207, 561, 366, 11, 9, 261, 214, 15, 216,
+ 218, 388, 205, 28, 276, -213, 462, 29, 20, 18,
+ 19, 282, 239, 222, 620, 621, 427, 10, 11, 23,
+ 174, 463, 632, 325, 622, 133, 27, 10, 11, -179,
+ -234, 273, 243, 458, 291, 579, 133, -213, 618, 26,
+ 111, 228, 228, 228, 10, 11, 111, 9, 146, 381,
+ 136, 208, 150, 367, 289, 228, 33, 134, 93, 257,
+ 164, 209, 537, 209, 228, 266, 124, 438, 134, 526,
+ 130, 528, 228, 439, 658, 492, 659, 150, 27, 228,
+ 501, 101, 503, 152, 156, 361, 29, 163, 638, -234,
+ 379, 607, 633, 331, 332, -234, 10, 11, 141, 9,
+ 164, 369, 228, 639, 640, 318, 652, 438, 624, 625,
+ 536, 79, 582, 487, 125, 438, 438, 349, 125, 586,
+ 451, 594, 613, 105, 357, 32, -181, 163, 243, 171,
+ 204, 397, 636, 516, 108, 102, 206, -265, 29, 363,
+ 523, 9, -265, 408, 198, 565, 414, 415, 10, 11,
+ -180, 228, -152, 228, 243, 79, 202, 409, -181, 411,
+ 451, -177, 203, 475, -175, 533, 403, 452, 430, 228,
+ 569, 228, 235, 489, 510, -180, 418, 228, 259, -264,
+ 512, 9, 235, 584, -264, -177, 150, -179, -175, 11,
+ 10, 11, -265, -177, 215, 496, -175, 219, -265, 228,
+ 497, 662, 220, 35, 122, 9, 223, 452, 37, 234,
+ 249, 410, 250, 94, 228, 228, 453, 112, 164, -176,
+ 408, 95, 47, 48, 9, 96, 79, 647, 165, 51,
+ 10, 11, 496, -174, -264, 97, 98, 497, -178, 209,
+ -264, 277, 262, -176, 353, 163, 495, 454, 480, 623,
+ 482, -176, 331, 332, 10, 11, 498, -174, 349, 61,
+ 354, 285, -178, 616, 520, -174, 226, 515, 99, 286,
+ -178, 64, 358, 10, 11, 483, 360, 243, 529, 478,
+ 231, 231, 231, 287, 490, 364, 362, 243, 228, 111,
+ 368, 514, 372, 626, 231, 374, 378, 111, 254, 380,
+ 228, 111, 481, 231, 146, 522, 150, 631, 257, 384,
+ 228, 231, 382, 199, 228, 386, 266, 200, 231, 394,
+ 507, 150, 392, 399, 401, 201, 165, 263, 164, 405,
+ 413, 416, 419, 264, 228, 228, 432, 445, 446, 254,
+ 448, 231, 79, 79, 480, 449, 482, 10, 11, 459,
+ 349, 542, 447, 549, 464, 163, 467, 468, 454, 469,
+ 480, 470, 482, 614, 454, 471, 165, 562, 349, 486,
+ 379, 483, 235, 491, 255, 509, 9, 79, 254, 117,
+ 585, 504, 243, 256, 9, 494, 9, 483, 10, 11,
+ 231, 506, 231, 511, 9, 513, 521, 164, 481, 525,
+ 527, 434, 9, 530, 531, 228, 532, 263, 231, 534,
+ 231, 127, 340, 264, 481, 535, 231, 554, 556, 143,
+ 557, 147, 265, 564, 163, 10, 11, 10, 11, 172,
+ 9, 520, 661, 10, 11, 10, 11, 317, 231, 568,
+ 463, 570, -156, 10, 11, 573, 575, 480, 228, 482,
+ 412, 10, 11, 231, 231, 117, 117, 117, 210, 210,
+ 577, 210, 210, 578, 235, 581, 288, 592, 593, 117,
+ 583, 595, 596, 529, 483, 243, 254, 597, 117, 10,
+ 11, 79, -157, 598, 165, 600, 117, 599, 150, 602,
+ 603, 334, 604, 117, 606, 608, 642, 615, 228, 627,
+ 335, 481, 349, 630, 542, 336, 337, 338, 549, 454,
+ 177, 255, 339, 349, 349, 480, 117, 482, 629, 340,
+ 185, 641, 438, 164, 189, 10, 11, 231, 648, 194,
+ 195, 196, 197, 649, 650, 651, 341, 657, 106, 231,
+ 66, 484, 483, 628, 580, 654, 590, 591, 342, 231,
+ 163, 370, 123, 231, 343, 371, 345, 11, 404, 493,
+ 284, 505, 355, 356, 352, 117, 476, 117, 91, 481,
+ 443, 444, 574, 231, 231, 344, 539, 563, 637, 634,
+ 559, 344, 344, 117, 351, 117, 0, 0, 0, 37,
+ 0, 117, 0, 0, 165, 0, 0, 0, 112, 0,
+ 0, 0, 0, 47, 48, 9, 0, 0, 0, 0,
+ 51, 0, 0, 117, 0, 0, 0, 224, 0, 0,
+ 0, 0, 0, 0, 137, 117, 0, 0, 117, 117,
+ 0, 0, 175, -274, 114, 0, 160, 484, 0, 169,
+ 225, 0, 0, 0, 231, 0, 280, 0, 0, 0,
+ 0, 0, 64, 484, 10, 11, 281, 0, 0, 0,
+ 0, 176, 177, 165, 178, 179, 180, 181, 182, 0,
+ 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197, 0, 450, 231, 0, 0,
+ 0, 0, 0, -274, 461, 0, 0, 0, 344, 0,
+ 0, 0, 117, -274, 0, 344, 0, 0, 0, 0,
+ 0, 0, 0, 344, 117, 0, 117, 0, 0, 0,
+ 0, 0, 0, 0, 117, 0, 0, 0, 117, 0,
+ 0, 0, 0, 0, 0, 0, 0, 231, 0, 0,
+ 484, 0, 0, 0, 0, 0, 0, 0, 117, 117,
+ 292, 293, 294, 295, 0, 296, 297, 298, 0, 299,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, 309,
+ 310, 311, 312, 0, 160, 0, 319, 0, 322, 0,
+ 0, 0, 137, 137, 333, 538, 0, 0, 0, 165,
+ 0, 545, 548, 0, 553, 0, 0, 0, 0, 0,
+ 0, 0, 0, 558, 344, 560, 0, 0, 484, 0,
+ 543, 344, 117, 344, 0, 0, 0, 0, 0, 117,
+ 0, 0, 344, 0, 344, 0, 0, 0, 117, 0,
+ 37, 0, 0, 35, 0, 0, 0, 0, 37, 112,
+ 0, 168, 0, 0, 47, 48, 9, 112, 0, 0,
+ 0, 51, 47, 48, 9, 137, 0, 0, 224, 51,
+ 0, 0, 117, 0, 0, 137, 55, 0, 0, 0,
+ 0, 0, 0, 0, 0, 114, 0, 0, 0, 56,
+ 57, 225, 58, 59, 0, 0, 60, 290, 421, 61,
+ 0, 0, 160, 64, 601, 10, 11, 281, 421, 62,
+ 63, 64, 605, 10, 11, 0, 0, 0, 37, 0,
+ 0, 241, 117, 344, 0, 117, 0, 112, 0, 0,
+ 0, 344, 47, 48, 9, 0, 0, 0, 344, 51,
+ 0, 0, 0, 0, 0, 0, 224, 0, 0, 0,
+ 0, 137, 137, 0, 545, 635, 0, 0, 0, 0,
+ 0, 0, 0, 114, 0, 0, 0, 0, 0, 225,
+ 344, 0, 0, 543, 344, 0, 0, 0, 0, -2,
+ 34, 64, 35, 10, 11, 36, 0, 37, 38, 39,
+ 137, 0, 40, 117, 41, 42, 43, 44, 45, 46,
+ 0, 47, 48, 9, 137, 0, 49, 50, 51, 52,
+ 53, 54, 160, 0, 0, 55, 0, 169, 0, 0,
+ 0, 0, 344, 0, 344, 0, 0, 0, 56, 57,
+ 0, 58, 59, 0, 0, 60, 0, 0, 61, 0,
+ 0, -24, 0, 0, 0, 0, 0, 0, 62, 63,
+ 64, 0, 10, 11, 0, 0, 0, 0, 566, 567,
+ 0, 0, 0, 0, 0, 0, 0, 0, 324, 0,
+ 35, 0, 0, 36, -249, 37, 38, 39, 0, -249,
+ 40, 160, 41, 42, 112, 44, 45, 46, 0, 47,
+ 48, 9, 0, 0, 49, 50, 51, 52, 53, 54,
+ 0, 421, 0, 55, 0, 0, 0, 0, 421, 588,
+ 421, 0, 0, 0, 0, 0, 56, 57, 0, 58,
+ 59, 0, 0, 60, 0, 0, 61, 0, 0, -249,
+ 0, 0, 0, 0, 325, -249, 62, 63, 64, 0,
+ 10, 11, 324, 0, 35, 0, 0, 36, 0, 37,
+ 38, 39, 0, 0, 40, 0, 41, 42, 112, 44,
+ 45, 46, 0, 47, 48, 9, 177, 0, 49, 50,
+ 51, 52, 53, 54, 0, 0, 185, 55, 0, 0,
189, 190, 191, 192, 193, 194, 195, 196, 197, 0,
- 0, 0, 117, 117, 292, 293, 294, 295, 0, 296,
- 297, 298, 0, 299, 300, 301, 302, 303, 304, 305,
- 306, 307, 308, 309, 310, 311, 312, 0, 160, 0,
- 319, 0, 322, 344, 0, 0, 137, 137, 333, 0,
- 344, 334, 0, 0, 0, 459, 0, 0, 344, 0,
- 175, 335, 0, 0, -269, 0, 336, 337, 338, 0,
- 0, 0, 0, 339, 0, 117, 0, 0, 0, 0,
- 340, 0, 117, 0, 0, 0, 0, 0, 0, 176,
- 177, 117, 178, 179, 180, 181, 182, 341, 183, 184,
- 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
- 195, 196, 197, 0, 0, 343, 0, 0, 11, 137,
- 0, -269, 0, 0, 0, 117, 0, 0, 0, 137,
- 0, -269, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 344, 0,
- 0, 0, 421, 0, 542, 344, 160, 344, 0, 0,
- 0, 0, 421, 0, -2, 34, 344, 35, 344, 36,
- 0, 37, 0, 38, 39, 117, 0, 40, 117, 41,
- 42, 43, 44, 45, 46, 0, 47, 48, 9, 0,
- 0, 49, 50, 51, 52, 53, 54, 0, 0, 0,
- 55, 0, 0, 0, 0, 137, 137, 0, 0, 0,
- 0, 0, 0, 56, 57, 0, 58, 59, 0, 0,
- 60, 0, 0, 61, 0, 0, -24, 0, 35, 0,
- 0, 0, 37, 62, 63, 64, 168, 10, 11, 0,
- 0, 0, 112, 0, 137, 117, 0, 47, 48, 9,
- 0, 0, 0, 0, 51, 0, 0, 344, 137, 0,
- 0, 55, 0, 0, 0, 344, 160, 0, 0, 0,
- 0, 169, 344, 0, 56, 57, 0, 58, 59, 0,
- 0, 60, 0, 0, 61, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 63, 64, 0, 10, 11,
- 0, 0, 0, 344, 0, 0, 542, 344, 0, 0,
- 0, 565, 566, 0, 0, 0, 0, 0, 0, 0,
- 0, 324, 0, 35, 0, 36, -244, 37, 0, 38,
- 39, 0, -244, 40, 160, 41, 42, 112, 44, 45,
- 46, 0, 47, 48, 9, 0, 0, 49, 50, 51,
- 52, 53, 54, 344, 421, 344, 55, 0, 0, 0,
- 0, 421, 586, 421, 0, 0, 0, 0, 0, 56,
- 57, 0, 58, 59, 0, 0, 60, 0, 0, 61,
- 0, 0, -244, 0, 0, 0, 0, 325, -244, 62,
- 63, 64, 0, 10, 11, 324, 0, 35, 0, 36,
- 0, 37, 0, 38, 39, 0, 0, 40, 0, 41,
- 42, 112, 44, 45, 46, 0, 47, 48, 9, 0,
- 0, 49, 50, 51, 52, 53, 54, 0, 0, 0,
- 55, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 56, 57, 0, 58, 59, 0, 0,
- 60, 0, 0, 61, 0, 35, -244, 642, 643, 37,
- 160, 325, -244, 62, 63, 64, 0, 10, 11, 112,
- 334, 0, 0, 0, 47, 48, 9, 0, 0, 0,
- 335, 51, 0, 0, 0, 336, 337, 338, 158, 0,
- 0, 0, 339, 0, 0, 0, 0, 0, 0, 340,
- 0, 56, 57, 0, 58, 159, 0, 0, 60, 0,
- 35, 61, 314, 0, 37, 0, 341, 0, 0, 0,
- 0, 62, 63, 64, 112, 10, 11, 0, 342, 47,
- 48, 9, 0, 0, 343, 0, 51, 11, 0, 0,
- 0, 0, 0, 55, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 56, 57, 0, 58,
- 59, 0, 0, 60, 0, 35, 61, 0, 0, 37,
- 0, 0, 0, 0, 420, 0, 62, 63, 64, 112,
- 10, 11, 0, 0, 47, 48, 9, 0, 0, 0,
- 0, 51, 0, 429, 0, 0, 0, 0, 158, 0,
+ 56, 57, 0, 58, 59, 0, 0, 60, 0, 0,
+ 61, 0, 0, -249, 645, 646, 0, 160, 325, -249,
+ 62, 63, 64, 35, 10, 11, 421, 0, 37, 0,
+ 0, 0, 0, 0, 0, 0, 0, 112, 0, 334,
+ 0, 0, 47, 48, 9, 0, 0, 0, 335, 51,
+ 0, 0, 0, 336, 337, 338, 158, 0, 0, 0,
+ 339, 0, 0, 0, 0, 0, 0, 340, 0, 56,
+ 57, 0, 58, 159, 0, 0, 60, 0, 35, 61,
+ 314, 0, 0, 37, 341, 0, 0, 0, 0, 62,
+ 63, 64, 112, 10, 11, 0, 0, 47, 48, 9,
+ 0, 0, 343, 0, 51, 11, 0, 0, 0, 0,
+ 0, 55, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 56, 57, 0, 58, 59, 0,
+ 0, 60, 0, 35, 61, 0, 0, 0, 37, 0,
+ 0, 0, 420, 0, 62, 63, 64, 112, 10, 11,
+ 0, 0, 47, 48, 9, 0, 0, 0, 0, 51,
+ 0, 429, 0, 0, 0, 0, 158, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,
+ 57, 0, 58, 159, 0, 0, 60, 0, 35, 61,
+ 0, 0, 0, 37, 0, 0, 0, 0, 0, 62,
+ 63, 64, 112, 10, 11, 0, 0, 47, 48, 9,
+ 0, 473, 0, 0, 51, 0, 0, 0, 0, 0,
+ 0, 55, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 56, 57, 0, 58, 59, 0,
+ 0, 60, 0, 35, 61, 0, 0, 0, 37, 0,
+ 0, 0, 0, 0, 62, 63, 64, 112, 10, 11,
+ 0, 0, 47, 48, 9, 0, 474, 0, 0, 51,
+ 0, 0, 0, 0, 0, 0, 55, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 35, 0, 0, 56,
+ 57, 37, 58, 59, 0, 0, 60, 0, 0, 61,
+ 112, 0, 0, 0, 0, 47, 48, 9, 0, 62,
+ 63, 64, 51, 10, 11, 0, 0, 0, 0, 55,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 56, 57, 0, 58, 159, 0, 0, 60, 0,
- 35, 61, 0, 0, 37, 0, 0, 0, 0, 0,
- 0, 62, 63, 64, 112, 10, 11, 0, 0, 47,
- 48, 9, 0, 472, 0, 0, 51, 0, 0, 0,
- 0, 0, 0, 55, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 56, 57, 0, 58,
- 59, 0, 0, 60, 0, 35, 61, 0, 0, 37,
- 0, 0, 0, 0, 0, 0, 62, 63, 64, 112,
- 10, 11, 0, 0, 47, 48, 9, 0, 473, 0,
- 0, 51, 0, 0, 0, 0, 0, 0, 55, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 56, 57, 0, 58, 59, 0, 0, 60, 0,
- 35, 61, 0, 0, 37, 0, 0, 0, 0, 0,
- 0, 62, 63, 64, 112, 10, 11, 0, 0, 47,
- 48, 9, 0, 0, 0, 0, 51, 0, 0, 0,
- 0, 0, 0, 55, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 56, 57, 0, 58,
- 59, 0, 0, 60, 0, 35, 61, 0, 0, 37,
- 0, 0, 0, 0, 0, 0, 62, 63, 64, 112,
- 10, 11, 0, 0, 47, 48, 9, 0, 0, 0,
- 0, 51, 0, 0, 0, 0, 0, 0, 158, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 56, 57, 0, 58, 159, 0, 0, 60, 0,
- 35, 61, 0, 0, 283, 0, 0, 0, 0, 0,
- 0, 62, 63, 64, 112, 10, 11, 0, 0, 47,
- 48, 9, 0, 0, 0, 0, 51, 0, 0, 0,
- 0, 0, 0, 55, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 56, 57, 0, 58,
- 59, 0, 0, 60, 0, 0, 61, 0, 0, 37,
- 0, 0, 0, 0, 0, 0, 62, 63, 64, 112,
- 10, 11, 0, 0, 47, 48, 9, 0, 0, 0,
- 0, 51, 0, 0, 0, 37, 0, 0, 224, 241,
- 0, 0, 0, 37, 0, 112, 0, 0, 0, 0,
- 47, 48, 9, 112, 0, 114, 0, 51, 47, 48,
- 9, 225, 0, 0, 224, 51, 0, 290, 37, 0,
- 0, 0, 113, 64, 0, 10, 11, 281, 112, 0,
- 0, 114, 0, 47, 48, 9, 0, 225, 0, 114,
- 51, 0, 0, 0, 0, 115, 37, 224, 0, 64,
- 0, 10, 11, 0, 0, 0, 112, 64, 0, 10,
- 11, 47, 48, 9, 114, 0, 0, 0, 51, 0,
- 225, 37, 0, 0, 0, 406, 0, 0, 0, 283,
- 0, 112, 64, 0, 10, 11, 47, 48, 9, 112,
- 0, 0, 114, 51, 47, 48, 9, 0, 407, 0,
- 224, 51, 0, 0, 334, 0, 0, 0, 224, 0,
- 64, 0, 10, 11, 335, 0, 0, 114, 0, 336,
- 337, 338, 0, 476, 0, 114, 339, 0, 0, 0,
- 0, 225, 334, 439, 0, 64, 0, 10, 11, 0,
- 0, 0, 335, 64, 0, 10, 11, 336, 337, 540,
- 341, 0, 0, 0, 339, 0, 440, 334, 0, 0,
- 0, 340, 0, 0, 0, 334, 0, 335, 343, 0,
- 0, 11, 336, 337, 338, 335, 0, 0, 341, 339,
- 336, 337, 338, 0, 0, 0, 340, 339, 0, 0,
- 0, 0, 0, 0, 340, 0, 343, 0, 10, 11,
- 0, 0, 0, 341, 0, 0, 0, 0, 0, 607,
- 0, 341, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 343, 0, 0, 11, 0, 0, 0, 0, 343,
- 176, 177, 11, 178, 0, 180, 181, 182, 0, 0,
- 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
- 194, 195, 196, 197, 0, 0, 0, 0, 0, 0,
- 176, 177, 0, 178, 0, 180, 181, 182, 0, 431,
- 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
- 194, 195, 196, 197, 176, 177, 0, 178, 0, 180,
- 181, 182, 0, 523, 184, 185, 186, 187, 188, 189,
- 190, 191, 192, 193, 194, 195, 196, 197, 176, 177,
- 0, 178, 0, 180, 181, 182, 0, 649, 184, 185,
+ 0, 0, 56, 57, 0, 58, 59, 0, 0, 60,
+ 0, 35, 61, 0, 0, 0, 37, 0, 0, 0,
+ 587, 0, 62, 63, 64, 112, 10, 11, 0, 0,
+ 47, 48, 9, 0, 0, 0, 0, 51, 0, 0,
+ 0, 0, 0, 0, 55, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 35, 0, 0, 56, 57, 37,
+ 58, 59, 0, 0, 60, 0, 0, 61, 112, 0,
+ 0, 0, 0, 47, 48, 9, 0, 62, 63, 64,
+ 51, 10, 11, 0, 0, 0, 0, 158, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+ 56, 57, 283, 58, 159, 0, 0, 60, 0, 0,
+ 61, 112, 0, 0, 0, 0, 47, 48, 9, 0,
+ 62, 63, 64, 51, 10, 11, 0, 0, 0, 0,
+ 55, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 56, 57, 37, 58, 59, 0, 0,
+ 60, 0, 0, 61, 112, 0, 0, 0, 0, 47,
+ 48, 9, 0, 62, 63, 64, 51, 10, 11, 0,
+ 37, 0, 0, 224, 0, 0, 0, 0, 37, 112,
+ 0, 0, 0, 0, 47, 48, 9, 112, 0, 0,
+ 114, 51, 47, 48, 9, 0, 225, 0, 113, 51,
+ 0, 0, 0, 0, 37, 0, 224, 0, 64, 0,
+ 10, 11, 396, 112, 0, 114, 0, 0, 47, 48,
+ 9, 115, 0, 114, 0, 51, 0, 0, 0, 225,
+ 0, 37, 406, 64, 0, 10, 11, 0, 0, 0,
+ 112, 64, 0, 10, 11, 47, 48, 9, 0, 114,
+ 0, 0, 51, 0, 0, 407, 0, 283, 0, 224,
+ 0, 0, 0, 0, 0, 334, 112, 64, 0, 10,
+ 11, 47, 48, 9, 335, 0, 114, 0, 51, 336,
+ 337, 338, 477, 0, 0, 224, 339, 0, 0, 0,
+ 334, 0, 0, 440, 64, 0, 10, 11, 334, 335,
+ 0, 460, 114, 0, 336, 337, 541, 335, 225, 0,
+ 341, 339, 336, 337, 338, 0, 441, 0, 340, 339,
+ 64, 0, 10, 11, 334, 0, 340, 0, 343, 0,
+ 0, 11, 0, 335, 0, 341, 0, 0, 336, 337,
+ 338, 0, 0, 341, 0, 339, 0, 0, 0, 0,
+ 0, 0, 340, 343, 0, 10, 11, 0, 0, 0,
+ 0, 343, 177, 0, 11, 0, 180, 181, 182, 341,
+ 0, 184, 185, 186, 187, 609, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197, 0, 0, 343, 176, 177,
+ 11, 178, 0, 180, 181, 182, 0, 0, 184, 185,
186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
- 196, 197, 176, 177, 0, 178, 0, 180, 181, 182,
- 0, 650, 184, 185, 186, 187, 188, 189, 190, 191,
- 192, 193, 194, 195, 196, 197, 0, 176, 177, 434,
- 178, 0, 180, 181, 182, 0, 0, 184, 185, 186,
+ 196, 197, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 176, 177, 0, 178, 0, 180, 181, 182, 0,
+ 434, 184, 185, 186, 187, 188, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197, 0, 0, 0, 0, 0,
+ 0, 176, 177, 0, 178, 0, 180, 181, 182, 0,
+ 431, 184, 185, 186, 187, 188, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197, 176, 177, 0, 178, 0,
+ 180, 181, 182, 0, 524, 184, 185, 186, 187, 188,
+ 189, 190, 191, 192, 193, 194, 195, 196, 197, 176,
+ 177, 0, 178, 0, 180, 181, 182, 0, 655, 184,
+ 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, 176, 177, 0, 178, 0, 180, 181,
+ 182, 0, 656, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 194, 195, 196, 197, 176, 177, 0,
+ 0, 0, 180, 181, 182, 0, 0, 184, 185, 186,
187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
197, 176, 177, 0, 0, 0, 180, 181, 182, 0,
- 0, 184, 185, 186, 187, 188, 189, 190, 191, 192,
- 193, 194, 195, 196, 197, 176, 177, 0, 0, 0,
- 180, 181, 182, 0, 0, 184, 185, 186, 187, 0,
- 189, 190, 191, 192, 193, 194, 195, 196, 197, 177,
- 0, 0, 0, 180, 181, 182, 0, 0, 184, 185,
- 186, 187, 0, 189, 190, 191, 192, 193, 194, 195,
- 196, 197
+ 0, 184, 185, 186, 187, 0, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-551))
-
-#define yytable_value_is_error(yytable_value) \
- YYID (0)
-
static const yytype_int16 yycheck[] =
{
- 5, 67, 250, 223, 37, 126, 37, 126, 143, 135,
- 201, 132, 204, 147, 61, 20, 36, 22, 485, 39,
- 31, 142, 28, 28, 321, 45, 452, 316, 323, 249,
- 258, 36, 3, 11, 39, 24, 263, 264, 43, 267,
- 45, 444, 67, 61, 594, 35, 0, 275, 53, 54,
- 6, 279, 1, 3, 1, 3, 12, 3, 24, 35,
- 59, 289, 67, 95, 63, 97, 98, 49, 3, 59,
- 59, 35, 71, 25, 24, 37, 24, 67, 24, 3,
- 37, 6, 24, 59, 389, 40, 35, 12, 35, 44,
- 24, 67, 397, 59, 644, 106, 646, 75, 20, 61,
- 24, 72, 50, 67, 61, 572, 172, 73, 74, 59,
- 59, 59, 68, 63, 60, 135, 8, 63, 67, 53,
- 67, 141, 127, 73, 74, 73, 74, 73, 74, 255,
- 135, 73, 74, 8, 62, 424, 141, 426, 143, 63,
- 437, 159, 147, 68, 126, 67, 25, 172, 62, 73,
- 74, 113, 114, 115, 68, 460, 113, 114, 115, 24,
- 6, 388, 382, 390, 3, 127, 12, 172, 21, 59,
- 127, 62, 639, 65, 136, 63, 602, 68, 60, 136,
- 24, 199, 144, 75, 74, 24, 8, 144, 436, 151,
- 65, 66, 595, 75, 151, 200, 62, 159, 503, 62,
- 75, 206, 159, 606, 607, 68, 35, 212, 113, 114,
- 115, 50, 174, 62, 220, 220, 62, 174, 223, 68,
- 515, 413, 68, 471, 62, 207, 208, 522, 420, 234,
- 59, 136, 40, 24, 73, 74, 44, 199, 67, 144,
- 3, 432, 199, 65, 249, 250, 151, 368, 3, 368,
- 283, 51, 283, 75, 559, 71, 476, 378, 384, 378,
- 62, 223, 67, 225, 399, 66, 223, 401, 225, 174,
- 317, 576, 577, 66, 3, 59, 281, 523, 524, 241,
- 59, 243, 24, 83, 241, 59, 243, 249, 74, 89,
- 518, 3, 249, 24, 599, 7, 6, 64, 280, 317,
- 62, 59, 12, 63, 75, 17, 59, 35, 290, 271,
- 22, 23, 24, 67, 271, 60, 321, 29, 60, 59,
- 225, 283, 35, 72, 286, 287, 283, 575, 72, 286,
- 287, 73, 74, 62, 63, 3, 241, 342, 211, 68,
- 24, 374, 60, 374, 217, 218, 59, 59, 353, 569,
- 416, 7, 62, 60, 67, 317, 374, 24, 68, 71,
- 317, 73, 74, 35, 384, 62, 271, 372, 60, 374,
- 75, 62, 392, 35, 379, 59, 396, 382, 283, 384,
- 427, 286, 287, 37, 366, 367, 53, 392, 24, 73,
- 74, 396, 59, 59, 399, 35, 401, 59, 360, 62,
- 3, 68, 72, 360, 62, 67, 73, 74, 65, 427,
- 372, 416, 374, 62, 62, 372, 67, 374, 62, 59,
- 382, 66, 65, 405, 386, 382, 59, 67, 67, 386,
- 71, 436, 437, 67, 7, 65, 469, 419, 469, 444,
- 445, 62, 447, 24, 406, 407, 567, 452, 567, 406,
- 407, 469, 485, 458, 485, 360, 461, 462, 62, 113,
- 114, 115, 62, 62, 60, 427, 471, 485, 341, 60,
- 427, 476, 9, 127, 60, 24, 349, 495, 59, 63,
- 17, 386, 136, 60, 21, 68, 24, 68, 60, 68,
- 144, 35, 73, 74, 31, 32, 60, 151, 60, 60,
- 75, 406, 407, 68, 53, 75, 60, 469, 60, 24,
- 59, 68, 469, 60, 476, 36, 582, 3, 60, 476,
- 174, 59, 62, 485, 73, 74, 72, 64, 485, 62,
- 24, 59, 24, 495, 75, 73, 74, 60, 495, 572,
- 66, 572, 60, 94, 95, 60, 97, 98, 55, 56,
- 57, 58, 59, 60, 572, 62, 63, 519, 73, 74,
- 60, 60, 519, 60, 569, 59, 439, 62, 60, 223,
- 575, 225, 445, 446, 621, 448, 24, 582, 60, 73,
- 74, 73, 74, 72, 457, 24, 459, 241, 60, 243,
- 595, 59, 597, 59, 59, 249, 601, 602, 68, 62,
- 62, 606, 607, 621, 68, 72, 639, 569, 639, 49,
- 572, 59, 569, 62, 519, 572, 59, 271, 60, 14,
- 59, 639, 68, 60, 68, 73, 74, 34, 49, 283,
- 60, 62, 286, 287, 73, 74, 60, 44, 60, 31,
- 61, 48, 60, 64, 60, 22, 53, 54, 55, 56,
- 582, 158, 159, 508, 615, 377, 615, 142, 243, 621,
- 211, 281, 524, 7, 621, 39, 217, 218, 159, 243,
- 213, 7, 392, 17, 372, 548, 384, 639, 22, 23,
- 24, 17, 639, 556, 22, 29, 22, 23, 24, 495,
- 440, 601, 36, 29, 462, 597, 334, 334, 212, 458,
- 36, -1, -1, -1, -1, -1, 360, -1, -1, 53,
- -1, -1, -1, -1, -1, 59, -1, 53, 372, -1,
- 374, 65, -1, 59, 597, 598, 34, 71, 382, 73,
- 74, 75, 386, -1, -1, 71, 44, 73, 74, 75,
+ 5, 37, 61, 37, 142, 67, 223, 377, 143, 323,
+ 389, 126, 258, 250, 204, 20, 147, 22, 397, 135,
+ 126, 267, 28, 28, 201, 49, 132, 453, 31, 275,
+ 445, 36, 249, 279, 39, 321, 142, 3, 43, 67,
+ 45, 486, 11, 289, 5, 263, 264, 24, 53, 54,
+ 36, 316, 61, 39, 3, 37, 24, 322, 24, 45,
+ 25, 1, 67, 113, 114, 115, 20, 0, 24, 59,
+ 55, 56, 57, 58, 59, 60, 53, 62, 63, 61,
+ 25, 5, 461, 5, 74, 24, 136, 95, 24, 97,
+ 98, 59, 1, 59, 144, 35, 60, 63, 21, 3,
+ 62, 151, 126, 106, 65, 66, 75, 73, 74, 24,
+ 172, 75, 596, 67, 75, 35, 3, 73, 74, 59,
+ 3, 60, 127, 72, 174, 504, 35, 67, 573, 63,
+ 135, 113, 114, 115, 73, 74, 141, 24, 143, 255,
+ 71, 65, 147, 65, 172, 127, 62, 67, 62, 135,
+ 159, 75, 438, 75, 136, 141, 40, 62, 67, 424,
+ 44, 426, 144, 68, 648, 382, 650, 172, 3, 151,
+ 388, 24, 390, 158, 159, 225, 63, 159, 604, 62,
+ 63, 560, 597, 207, 208, 68, 73, 74, 51, 24,
+ 199, 241, 174, 608, 609, 200, 641, 62, 577, 578,
+ 437, 206, 516, 68, 40, 62, 62, 212, 44, 523,
+ 3, 68, 68, 3, 220, 220, 35, 199, 223, 62,
+ 83, 271, 601, 413, 3, 60, 89, 7, 63, 234,
+ 420, 24, 12, 283, 67, 472, 286, 287, 73, 74,
+ 59, 223, 66, 225, 249, 250, 66, 283, 67, 283,
+ 3, 35, 59, 368, 35, 432, 280, 50, 317, 241,
+ 477, 243, 368, 378, 399, 59, 290, 249, 384, 7,
+ 401, 24, 378, 519, 12, 59, 281, 59, 59, 74,
+ 73, 74, 62, 67, 24, 7, 67, 64, 68, 271,
+ 12, 661, 62, 3, 37, 24, 59, 50, 8, 63,
+ 59, 283, 67, 9, 286, 287, 59, 17, 317, 35,
+ 360, 17, 22, 23, 24, 21, 321, 631, 61, 29,
+ 73, 74, 7, 35, 62, 31, 32, 12, 35, 75,
+ 68, 60, 35, 59, 59, 317, 386, 342, 374, 576,
+ 374, 67, 366, 367, 73, 74, 68, 59, 353, 59,
+ 3, 60, 59, 570, 416, 67, 406, 407, 64, 72,
+ 67, 71, 60, 73, 74, 374, 8, 372, 427, 374,
+ 113, 114, 115, 72, 379, 35, 60, 382, 360, 384,
+ 62, 405, 75, 68, 127, 60, 62, 392, 24, 24,
+ 372, 396, 374, 136, 399, 419, 401, 587, 384, 62,
+ 382, 144, 59, 59, 386, 72, 392, 63, 151, 3,
+ 396, 416, 62, 62, 62, 71, 159, 53, 427, 65,
+ 67, 62, 65, 59, 406, 407, 66, 59, 67, 24,
+ 67, 174, 437, 438, 470, 8, 470, 73, 74, 65,
+ 445, 446, 71, 448, 62, 427, 62, 62, 453, 62,
+ 486, 60, 486, 568, 459, 60, 199, 462, 463, 60,
+ 63, 470, 568, 60, 59, 35, 24, 472, 24, 37,
+ 520, 60, 477, 68, 24, 68, 24, 486, 73, 74,
+ 223, 68, 225, 60, 24, 60, 60, 496, 470, 75,
+ 68, 75, 24, 60, 60, 477, 60, 53, 241, 60,
+ 243, 59, 36, 59, 486, 68, 249, 3, 62, 59,
+ 72, 59, 68, 60, 496, 73, 74, 73, 74, 59,
+ 24, 583, 660, 73, 74, 73, 74, 59, 271, 62,
+ 75, 59, 59, 73, 74, 60, 66, 573, 520, 573,
+ 283, 73, 74, 286, 287, 113, 114, 115, 94, 95,
+ 60, 97, 98, 60, 660, 60, 60, 60, 72, 127,
+ 62, 60, 60, 622, 573, 570, 24, 59, 136, 73,
+ 74, 576, 59, 68, 317, 72, 144, 62, 583, 68,
+ 62, 8, 49, 151, 62, 59, 14, 60, 570, 68,
+ 17, 573, 597, 68, 599, 22, 23, 24, 603, 604,
+ 34, 59, 29, 608, 609, 641, 174, 641, 60, 36,
+ 44, 60, 62, 622, 48, 73, 74, 360, 60, 53,
+ 54, 55, 56, 60, 60, 60, 53, 68, 31, 372,
+ 22, 374, 641, 583, 509, 642, 525, 525, 65, 382,
+ 622, 243, 39, 386, 71, 243, 211, 74, 281, 384,
+ 159, 392, 217, 218, 213, 223, 372, 225, 22, 641,
+ 334, 334, 496, 406, 407, 211, 441, 463, 603, 599,
+ 459, 217, 218, 241, 212, 243, -1, -1, -1, 8,
+ -1, 249, -1, -1, 427, -1, -1, -1, 17, -1,
+ -1, -1, -1, 22, 23, 24, -1, -1, -1, -1,
+ 29, -1, -1, 271, -1, -1, -1, 36, -1, -1,
+ -1, -1, -1, -1, 49, 283, -1, -1, 286, 287,
+ -1, -1, 4, 5, 53, -1, 61, 470, -1, 64,
+ 59, -1, -1, -1, 477, -1, 65, -1, -1, -1,
+ -1, -1, 71, 486, 73, 74, 75, -1, -1, -1,
+ -1, 33, 34, 496, 36, 37, 38, 39, 40, -1,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, -1, 341, 520, -1, -1,
+ -1, -1, -1, 65, 349, -1, -1, -1, 334, -1,
+ -1, -1, 360, 75, -1, 341, -1, -1, -1, -1,
+ -1, -1, -1, 349, 372, -1, 374, -1, -1, -1,
+ -1, -1, -1, -1, 382, -1, -1, -1, 386, -1,
+ -1, -1, -1, -1, -1, -1, -1, 570, -1, -1,
+ 573, -1, -1, -1, -1, -1, -1, -1, 406, 407,
+ 175, 176, 177, 178, -1, 180, 181, 182, -1, 184,
+ 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, -1, 199, -1, 201, -1, 203, -1,
+ -1, -1, 207, 208, 209, 440, -1, -1, -1, 622,
+ -1, 446, 447, -1, 449, -1, -1, -1, -1, -1,
+ -1, -1, -1, 458, 440, 460, -1, -1, 641, -1,
+ 446, 447, 470, 449, -1, -1, -1, -1, -1, 477,
+ -1, -1, 458, -1, 460, -1, -1, -1, 486, -1,
+ 8, -1, -1, 3, -1, -1, -1, -1, 8, 17,
+ -1, 11, -1, -1, 22, 23, 24, 17, -1, -1,
+ -1, 29, 22, 23, 24, 280, -1, -1, 36, 29,
+ -1, -1, 520, -1, -1, 290, 36, -1, -1, -1,
+ -1, -1, -1, -1, -1, 53, -1, -1, -1, 49,
+ 50, 59, 52, 53, -1, -1, 56, 65, 313, 59,
+ -1, -1, 317, 71, 549, 73, 74, 75, 323, 69,
+ 70, 71, 557, 73, 74, -1, -1, -1, 8, -1,
+ -1, 11, 570, 549, -1, 573, -1, 17, -1, -1,
+ -1, 557, 22, 23, 24, -1, -1, -1, 564, 29,
+ -1, -1, -1, -1, -1, -1, 36, -1, -1, -1,
+ -1, 366, 367, -1, 599, 600, -1, -1, -1, -1,
+ -1, -1, -1, 53, -1, -1, -1, -1, -1, 59,
+ 596, -1, -1, 599, 600, -1, -1, -1, -1, 0,
+ 1, 71, 3, 73, 74, 6, -1, 8, 9, 10,
+ 405, -1, 13, 641, 15, 16, 17, 18, 19, 20,
+ -1, 22, 23, 24, 419, -1, 27, 28, 29, 30,
+ 31, 32, 427, -1, -1, 36, -1, 432, -1, -1,
+ -1, -1, 648, -1, 650, -1, -1, -1, 49, 50,
+ -1, 52, 53, -1, -1, 56, -1, -1, 59, -1,
+ -1, 62, -1, -1, -1, -1, -1, -1, 69, 70,
+ 71, -1, 73, 74, -1, -1, -1, -1, 473, 474,
+ -1, -1, -1, -1, -1, -1, -1, -1, 1, -1,
+ 3, -1, -1, 6, 7, 8, 9, 10, -1, 12,
+ 13, 496, 15, 16, 17, 18, 19, 20, -1, 22,
+ 23, 24, -1, -1, 27, 28, 29, 30, 31, 32,
+ -1, 516, -1, 36, -1, -1, -1, -1, 523, 524,
+ 525, -1, -1, -1, -1, -1, 49, 50, -1, 52,
+ 53, -1, -1, 56, -1, -1, 59, -1, -1, 62,
+ -1, -1, -1, -1, 67, 68, 69, 70, 71, -1,
+ 73, 74, 1, -1, 3, -1, -1, 6, -1, 8,
+ 9, 10, -1, -1, 13, -1, 15, 16, 17, 18,
+ 19, 20, -1, 22, 23, 24, 34, -1, 27, 28,
+ 29, 30, 31, 32, -1, -1, 44, 36, -1, -1,
48, 49, 50, 51, 52, 53, 54, 55, 56, -1,
- -1, -1, 406, 407, 175, 176, 177, 178, -1, 180,
- 181, 182, -1, 184, 185, 186, 187, 188, 189, 190,
- 191, 192, 193, 194, 195, 196, 197, -1, 199, -1,
- 201, -1, 203, 334, -1, -1, 207, 208, 209, -1,
- 341, 7, -1, -1, -1, 11, -1, -1, 349, -1,
- 4, 17, -1, -1, 8, -1, 22, 23, 24, -1,
- -1, -1, -1, 29, -1, 469, -1, -1, -1, -1,
- 36, -1, 476, -1, -1, -1, -1, -1, -1, 33,
- 34, 485, 36, 37, 38, 39, 40, 53, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, -1, -1, 71, -1, -1, 74, 280,
- -1, 65, -1, -1, -1, 519, -1, -1, -1, 290,
- -1, 75, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 439, -1,
- -1, -1, 313, -1, 445, 446, 317, 448, -1, -1,
- -1, -1, 323, -1, 0, 1, 457, 3, 459, 5,
- -1, 7, -1, 9, 10, 569, -1, 13, 572, 15,
- 16, 17, 18, 19, 20, -1, 22, 23, 24, -1,
- -1, 27, 28, 29, 30, 31, 32, -1, -1, -1,
- 36, -1, -1, -1, -1, 366, 367, -1, -1, -1,
- -1, -1, -1, 49, 50, -1, 52, 53, -1, -1,
- 56, -1, -1, 59, -1, -1, 62, -1, 3, -1,
- -1, -1, 7, 69, 70, 71, 11, 73, 74, -1,
- -1, -1, 17, -1, 405, 639, -1, 22, 23, 24,
- -1, -1, -1, -1, 29, -1, -1, 548, 419, -1,
- -1, 36, -1, -1, -1, 556, 427, -1, -1, -1,
- -1, 432, 563, -1, 49, 50, -1, 52, 53, -1,
- -1, 56, -1, -1, 59, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 69, 70, 71, -1, 73, 74,
- -1, -1, -1, 594, -1, -1, 597, 598, -1, -1,
- -1, 472, 473, -1, -1, -1, -1, -1, -1, -1,
- -1, 1, -1, 3, -1, 5, 6, 7, -1, 9,
- 10, -1, 12, 13, 495, 15, 16, 17, 18, 19,
- 20, -1, 22, 23, 24, -1, -1, 27, 28, 29,
- 30, 31, 32, 644, 515, 646, 36, -1, -1, -1,
- -1, 522, 523, 524, -1, -1, -1, -1, -1, 49,
- 50, -1, 52, 53, -1, -1, 56, -1, -1, 59,
- -1, -1, 62, -1, -1, -1, -1, 67, 68, 69,
- 70, 71, -1, 73, 74, 1, -1, 3, -1, 5,
- -1, 7, -1, 9, 10, -1, -1, 13, -1, 15,
- 16, 17, 18, 19, 20, -1, 22, 23, 24, -1,
- -1, 27, 28, 29, 30, 31, 32, -1, -1, -1,
- 36, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 49, 50, -1, 52, 53, -1, -1,
- 56, -1, -1, 59, -1, 3, 62, 618, 619, 7,
- 621, 67, 68, 69, 70, 71, -1, 73, 74, 17,
- 7, -1, -1, -1, 22, 23, 24, -1, -1, -1,
- 17, 29, -1, -1, -1, 22, 23, 24, 36, -1,
- -1, -1, 29, -1, -1, -1, -1, -1, -1, 36,
- -1, 49, 50, -1, 52, 53, -1, -1, 56, -1,
- 3, 59, 60, -1, 7, -1, 53, -1, -1, -1,
- -1, 69, 70, 71, 17, 73, 74, -1, 65, 22,
- 23, 24, -1, -1, 71, -1, 29, 74, -1, -1,
- -1, -1, -1, 36, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 49, 50, -1, 52,
- 53, -1, -1, 56, -1, 3, 59, -1, -1, 7,
- -1, -1, -1, -1, 67, -1, 69, 70, 71, 17,
- 73, 74, -1, -1, 22, 23, 24, -1, -1, -1,
- -1, 29, -1, 31, -1, -1, -1, -1, 36, -1,
+ 49, 50, -1, 52, 53, -1, -1, 56, -1, -1,
+ 59, -1, -1, 62, 619, 620, -1, 622, 67, 68,
+ 69, 70, 71, 3, 73, 74, 631, -1, 8, -1,
+ -1, -1, -1, -1, -1, -1, -1, 17, -1, 8,
+ -1, -1, 22, 23, 24, -1, -1, -1, 17, 29,
+ -1, -1, -1, 22, 23, 24, 36, -1, -1, -1,
+ 29, -1, -1, -1, -1, -1, -1, 36, -1, 49,
+ 50, -1, 52, 53, -1, -1, 56, -1, 3, 59,
+ 60, -1, -1, 8, 53, -1, -1, -1, -1, 69,
+ 70, 71, 17, 73, 74, -1, -1, 22, 23, 24,
+ -1, -1, 71, -1, 29, 74, -1, -1, -1, -1,
+ -1, 36, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 49, 50, -1, 52, 53, -1,
+ -1, 56, -1, 3, 59, -1, -1, -1, 8, -1,
+ -1, -1, 67, -1, 69, 70, 71, 17, 73, 74,
+ -1, -1, 22, 23, 24, -1, -1, -1, -1, 29,
+ -1, 31, -1, -1, -1, -1, 36, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 49,
+ 50, -1, 52, 53, -1, -1, 56, -1, 3, 59,
+ -1, -1, -1, 8, -1, -1, -1, -1, -1, 69,
+ 70, 71, 17, 73, 74, -1, -1, 22, 23, 24,
+ -1, 26, -1, -1, 29, -1, -1, -1, -1, -1,
+ -1, 36, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 49, 50, -1, 52, 53, -1,
+ -1, 56, -1, 3, 59, -1, -1, -1, 8, -1,
+ -1, -1, -1, -1, 69, 70, 71, 17, 73, 74,
+ -1, -1, 22, 23, 24, -1, 26, -1, -1, 29,
+ -1, -1, -1, -1, -1, -1, 36, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 3, -1, -1, 49,
+ 50, 8, 52, 53, -1, -1, 56, -1, -1, 59,
+ 17, -1, -1, -1, -1, 22, 23, 24, -1, 69,
+ 70, 71, 29, 73, 74, -1, -1, -1, -1, 36,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 49, 50, -1, 52, 53, -1, -1, 56, -1,
- 3, 59, -1, -1, 7, -1, -1, -1, -1, -1,
- -1, 69, 70, 71, 17, 73, 74, -1, -1, 22,
- 23, 24, -1, 26, -1, -1, 29, -1, -1, -1,
- -1, -1, -1, 36, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 49, 50, -1, 52,
- 53, -1, -1, 56, -1, 3, 59, -1, -1, 7,
- -1, -1, -1, -1, -1, -1, 69, 70, 71, 17,
- 73, 74, -1, -1, 22, 23, 24, -1, 26, -1,
- -1, 29, -1, -1, -1, -1, -1, -1, 36, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 49, 50, -1, 52, 53, -1, -1, 56, -1,
- 3, 59, -1, -1, 7, -1, -1, -1, -1, -1,
- -1, 69, 70, 71, 17, 73, 74, -1, -1, 22,
- 23, 24, -1, -1, -1, -1, 29, -1, -1, -1,
- -1, -1, -1, 36, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 49, 50, -1, 52,
- 53, -1, -1, 56, -1, 3, 59, -1, -1, 7,
- -1, -1, -1, -1, -1, -1, 69, 70, 71, 17,
- 73, 74, -1, -1, 22, 23, 24, -1, -1, -1,
- -1, 29, -1, -1, -1, -1, -1, -1, 36, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 49, 50, -1, 52, 53, -1, -1, 56, -1,
- 3, 59, -1, -1, 7, -1, -1, -1, -1, -1,
- -1, 69, 70, 71, 17, 73, 74, -1, -1, 22,
- 23, 24, -1, -1, -1, -1, 29, -1, -1, -1,
- -1, -1, -1, 36, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 49, 50, -1, 52,
- 53, -1, -1, 56, -1, -1, 59, -1, -1, 7,
- -1, -1, -1, -1, -1, -1, 69, 70, 71, 17,
- 73, 74, -1, -1, 22, 23, 24, -1, -1, -1,
- -1, 29, -1, -1, -1, 7, -1, -1, 36, 11,
- -1, -1, -1, 7, -1, 17, -1, -1, -1, -1,
- 22, 23, 24, 17, -1, 53, -1, 29, 22, 23,
- 24, 59, -1, -1, 36, 29, -1, 65, 7, -1,
- -1, -1, 36, 71, -1, 73, 74, 75, 17, -1,
- -1, 53, -1, 22, 23, 24, -1, 59, -1, 53,
- 29, -1, -1, -1, -1, 59, 7, 36, -1, 71,
- -1, 73, 74, -1, -1, -1, 17, 71, -1, 73,
- 74, 22, 23, 24, 53, -1, -1, -1, 29, -1,
- 59, 7, -1, -1, -1, 36, -1, -1, -1, 7,
- -1, 17, 71, -1, 73, 74, 22, 23, 24, 17,
- -1, -1, 53, 29, 22, 23, 24, -1, 59, -1,
- 36, 29, -1, -1, 7, -1, -1, -1, 36, -1,
- 71, -1, 73, 74, 17, -1, -1, 53, -1, 22,
- 23, 24, -1, 59, -1, 53, 29, -1, -1, -1,
- -1, 59, 7, 36, -1, 71, -1, 73, 74, -1,
- -1, -1, 17, 71, -1, 73, 74, 22, 23, 24,
- 53, -1, -1, -1, 29, -1, 59, 7, -1, -1,
- -1, 36, -1, -1, -1, 7, -1, 17, 71, -1,
- -1, 74, 22, 23, 24, 17, -1, -1, 53, 29,
- 22, 23, 24, -1, -1, -1, 36, 29, -1, -1,
- -1, -1, -1, -1, 36, -1, 71, -1, 73, 74,
- -1, -1, -1, 53, -1, -1, -1, -1, -1, 59,
- -1, 53, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 71, -1, -1, 74, -1, -1, -1, -1, 71,
- 33, 34, 74, 36, -1, 38, 39, 40, -1, -1,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, -1, -1, -1, -1, -1, -1,
- 33, 34, -1, 36, -1, 38, 39, 40, -1, 72,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 33, 34, -1, 36, -1, 38,
- 39, 40, -1, 66, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 33, 34,
- -1, 36, -1, 38, 39, 40, -1, 66, 43, 44,
+ -1, -1, 49, 50, -1, 52, 53, -1, -1, 56,
+ -1, 3, 59, -1, -1, -1, 8, -1, -1, -1,
+ 67, -1, 69, 70, 71, 17, 73, 74, -1, -1,
+ 22, 23, 24, -1, -1, -1, -1, 29, -1, -1,
+ -1, -1, -1, -1, 36, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 3, -1, -1, 49, 50, 8,
+ 52, 53, -1, -1, 56, -1, -1, 59, 17, -1,
+ -1, -1, -1, 22, 23, 24, -1, 69, 70, 71,
+ 29, 73, 74, -1, -1, -1, -1, 36, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 3, -1, -1,
+ 49, 50, 8, 52, 53, -1, -1, 56, -1, -1,
+ 59, 17, -1, -1, -1, -1, 22, 23, 24, -1,
+ 69, 70, 71, 29, 73, 74, -1, -1, -1, -1,
+ 36, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 49, 50, 8, 52, 53, -1, -1,
+ 56, -1, -1, 59, 17, -1, -1, -1, -1, 22,
+ 23, 24, -1, 69, 70, 71, 29, 73, 74, -1,
+ 8, -1, -1, 36, -1, -1, -1, -1, 8, 17,
+ -1, -1, -1, -1, 22, 23, 24, 17, -1, -1,
+ 53, 29, 22, 23, 24, -1, 59, -1, 36, 29,
+ -1, -1, -1, -1, 8, -1, 36, -1, 71, -1,
+ 73, 74, 75, 17, -1, 53, -1, -1, 22, 23,
+ 24, 59, -1, 53, -1, 29, -1, -1, -1, 59,
+ -1, 8, 36, 71, -1, 73, 74, -1, -1, -1,
+ 17, 71, -1, 73, 74, 22, 23, 24, -1, 53,
+ -1, -1, 29, -1, -1, 59, -1, 8, -1, 36,
+ -1, -1, -1, -1, -1, 8, 17, 71, -1, 73,
+ 74, 22, 23, 24, 17, -1, 53, -1, 29, 22,
+ 23, 24, 59, -1, -1, 36, 29, -1, -1, -1,
+ 8, -1, -1, 36, 71, -1, 73, 74, 8, 17,
+ -1, 11, 53, -1, 22, 23, 24, 17, 59, -1,
+ 53, 29, 22, 23, 24, -1, 59, -1, 36, 29,
+ 71, -1, 73, 74, 8, -1, 36, -1, 71, -1,
+ -1, 74, -1, 17, -1, 53, -1, -1, 22, 23,
+ 24, -1, -1, 53, -1, 29, -1, -1, -1, -1,
+ -1, -1, 36, 71, -1, 73, 74, -1, -1, -1,
+ -1, 71, 34, -1, 74, -1, 38, 39, 40, 53,
+ -1, 43, 44, 45, 46, 59, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, -1, -1, 71, 33, 34,
+ 74, 36, -1, 38, 39, 40, -1, -1, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 33, 34, -1, 36, -1, 38, 39, 40,
- -1, 66, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, -1, 33, 34, 60,
- 36, -1, 38, 39, 40, -1, -1, 43, 44, 45,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 33, 34, -1, 36, -1, 38, 39, 40, -1,
+ 75, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, -1, -1, -1, -1, -1,
+ -1, 33, 34, -1, 36, -1, 38, 39, 40, -1,
+ 72, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 33, 34, -1, 36, -1,
+ 38, 39, 40, -1, 66, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 33,
+ 34, -1, 36, -1, 38, 39, 40, -1, 66, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 33, 34, -1, 36, -1, 38, 39,
+ 40, -1, 66, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 33, 34, -1,
+ -1, -1, 38, 39, 40, -1, -1, 43, 44, 45,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
56, 33, 34, -1, -1, -1, 38, 39, 40, -1,
- -1, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 33, 34, -1, -1, -1,
- 38, 39, 40, -1, -1, 43, 44, 45, 46, -1,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 34,
- -1, -1, -1, 38, 39, 40, -1, -1, 43, 44,
- 45, 46, -1, 48, 49, 50, 51, 52, 53, 54,
- 55, 56
+ -1, 43, 44, 45, 46, -1, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1488,71 +1485,72 @@ static const yytype_int16 yycheck[] =
static const yytype_uint8 yystos[] =
{
0, 77, 79, 80, 0, 25, 78, 25, 86, 24,
- 73, 74, 137, 138, 81, 24, 88, 89, 3, 62,
- 21, 82, 162, 24, 87, 210, 63, 3, 59, 63,
- 83, 85, 137, 62, 1, 3, 5, 7, 9, 10,
+ 73, 74, 141, 142, 81, 24, 88, 89, 3, 62,
+ 21, 82, 166, 24, 87, 214, 63, 3, 59, 63,
+ 83, 85, 141, 62, 1, 3, 6, 8, 9, 10,
13, 15, 16, 17, 18, 19, 20, 22, 23, 27,
28, 29, 30, 31, 32, 36, 49, 50, 52, 53,
56, 59, 69, 70, 71, 90, 91, 92, 98, 110,
- 113, 118, 121, 123, 124, 125, 126, 130, 134, 137,
- 139, 140, 145, 146, 149, 152, 153, 154, 157, 160,
- 161, 177, 182, 62, 9, 17, 21, 31, 32, 64,
- 195, 24, 60, 83, 84, 3, 86, 88, 3, 134,
- 136, 137, 17, 36, 53, 59, 137, 139, 144, 148,
- 149, 150, 157, 136, 125, 130, 111, 59, 137, 155,
- 125, 134, 114, 35, 67, 133, 71, 123, 182, 189,
- 122, 133, 119, 59, 96, 97, 137, 59, 93, 135,
- 137, 181, 124, 124, 124, 124, 124, 124, 36, 53,
- 123, 131, 143, 149, 151, 157, 124, 124, 11, 123,
- 188, 62, 59, 94, 181, 4, 33, 34, 36, 37,
+ 113, 121, 124, 126, 127, 128, 129, 134, 138, 141,
+ 143, 144, 149, 150, 153, 156, 157, 158, 161, 164,
+ 165, 181, 186, 62, 9, 17, 21, 31, 32, 64,
+ 199, 24, 60, 83, 84, 3, 86, 88, 3, 138,
+ 140, 141, 17, 36, 53, 59, 141, 143, 148, 152,
+ 153, 154, 161, 140, 128, 134, 111, 59, 141, 159,
+ 128, 138, 114, 35, 67, 137, 71, 126, 186, 193,
+ 125, 137, 122, 59, 96, 97, 141, 59, 93, 139,
+ 141, 185, 127, 127, 127, 127, 127, 127, 36, 53,
+ 126, 135, 147, 153, 155, 161, 127, 127, 11, 126,
+ 192, 62, 59, 94, 185, 4, 33, 34, 36, 37,
38, 39, 40, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 67, 59,
- 63, 71, 66, 59, 133, 1, 133, 8, 65, 75,
- 138, 196, 59, 156, 196, 24, 196, 197, 196, 64,
- 62, 186, 88, 59, 36, 59, 142, 148, 149, 150,
- 151, 157, 142, 142, 63, 98, 107, 108, 109, 182,
- 190, 11, 132, 137, 141, 142, 173, 174, 175, 59,
- 67, 158, 112, 190, 24, 59, 68, 134, 167, 169,
- 171, 142, 35, 53, 59, 68, 134, 166, 168, 169,
- 170, 180, 112, 60, 97, 165, 142, 60, 93, 163,
- 65, 75, 142, 7, 143, 60, 72, 72, 60, 94,
- 65, 142, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 127, 60, 131, 183, 59, 137, 123,
- 188, 178, 123, 127, 1, 67, 91, 100, 176, 177,
- 179, 182, 182, 123, 7, 17, 22, 23, 24, 29,
- 36, 53, 65, 71, 138, 198, 200, 201, 202, 137,
- 203, 211, 158, 59, 3, 198, 198, 83, 60, 175,
- 7, 142, 60, 137, 35, 105, 8, 65, 62, 142,
- 132, 141, 75, 187, 60, 175, 179, 115, 62, 63,
- 24, 169, 59, 172, 62, 186, 72, 104, 59, 170,
- 53, 170, 62, 186, 3, 194, 75, 142, 120, 62,
- 186, 62, 186, 182, 135, 65, 36, 59, 142, 148,
- 149, 150, 157, 67, 142, 142, 62, 186, 182, 65,
- 67, 123, 128, 129, 184, 185, 11, 75, 187, 31,
- 131, 72, 66, 176, 60, 185, 101, 62, 68, 36,
- 59, 199, 200, 202, 59, 67, 71, 67, 7, 198,
- 3, 50, 59, 137, 208, 209, 3, 72, 65, 11,
- 198, 60, 75, 62, 191, 211, 62, 62, 62, 60,
- 60, 106, 26, 26, 190, 173, 59, 137, 147, 148,
- 149, 150, 151, 157, 159, 60, 68, 105, 190, 137,
- 60, 175, 171, 68, 142, 6, 12, 68, 99, 102,
- 170, 194, 170, 60, 168, 68, 134, 194, 35, 97,
- 60, 93, 60, 182, 142, 127, 94, 95, 164, 181,
- 60, 182, 127, 66, 75, 187, 68, 75, 187, 131,
- 60, 60, 60, 188, 68, 179, 176, 198, 201, 191,
- 24, 137, 138, 193, 198, 205, 213, 198, 137, 192,
- 204, 212, 198, 3, 208, 62, 72, 198, 209, 198,
- 194, 137, 203, 60, 179, 123, 123, 62, 175, 59,
- 159, 116, 60, 183, 66, 103, 60, 60, 194, 104,
- 60, 185, 62, 186, 142, 185, 123, 129, 128, 129,
- 60, 72, 68, 60, 60, 59, 68, 62, 72, 198,
- 68, 62, 49, 198, 62, 194, 59, 59, 198, 206,
- 207, 68, 190, 60, 175, 14, 117, 159, 8, 65,
- 66, 75, 179, 194, 194, 68, 68, 95, 60, 68,
- 206, 191, 205, 198, 194, 204, 208, 191, 191, 60,
- 100, 113, 123, 123, 60, 60, 60, 60, 159, 66,
- 66, 206, 206
+ 63, 71, 66, 59, 137, 1, 137, 5, 65, 75,
+ 142, 200, 59, 160, 200, 24, 200, 201, 200, 64,
+ 62, 190, 88, 59, 36, 59, 146, 152, 153, 154,
+ 155, 161, 146, 146, 63, 98, 107, 108, 109, 186,
+ 194, 11, 136, 141, 145, 146, 177, 178, 179, 59,
+ 67, 162, 112, 194, 24, 59, 68, 138, 171, 173,
+ 175, 146, 35, 53, 59, 68, 138, 170, 172, 173,
+ 174, 184, 112, 60, 97, 169, 146, 60, 93, 167,
+ 65, 75, 146, 8, 147, 60, 72, 72, 60, 94,
+ 65, 146, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 130, 60, 135, 187, 59, 141, 126,
+ 192, 182, 126, 130, 1, 67, 91, 100, 180, 181,
+ 183, 186, 186, 126, 8, 17, 22, 23, 24, 29,
+ 36, 53, 65, 71, 142, 202, 204, 205, 206, 141,
+ 207, 215, 162, 59, 3, 202, 202, 83, 60, 179,
+ 8, 146, 60, 141, 35, 105, 5, 65, 62, 146,
+ 136, 145, 75, 191, 60, 179, 183, 115, 62, 63,
+ 24, 173, 59, 176, 62, 190, 72, 104, 59, 174,
+ 53, 174, 62, 190, 3, 198, 75, 146, 123, 62,
+ 190, 62, 190, 186, 139, 65, 36, 59, 146, 152,
+ 153, 154, 161, 67, 146, 146, 62, 190, 186, 65,
+ 67, 126, 131, 132, 188, 189, 11, 75, 191, 31,
+ 135, 72, 66, 180, 75, 191, 189, 101, 62, 68,
+ 36, 59, 203, 204, 206, 59, 67, 71, 67, 8,
+ 202, 3, 50, 59, 141, 212, 213, 3, 72, 65,
+ 11, 202, 60, 75, 62, 195, 215, 62, 62, 62,
+ 60, 60, 106, 26, 26, 194, 177, 59, 141, 151,
+ 152, 153, 154, 155, 161, 163, 60, 68, 105, 194,
+ 141, 60, 179, 175, 68, 146, 7, 12, 68, 99,
+ 102, 174, 198, 174, 60, 172, 68, 138, 198, 35,
+ 97, 60, 93, 60, 186, 146, 130, 94, 95, 168,
+ 185, 60, 186, 130, 66, 75, 191, 68, 191, 135,
+ 60, 60, 60, 192, 60, 68, 183, 180, 202, 205,
+ 195, 24, 141, 142, 197, 202, 209, 217, 202, 141,
+ 196, 208, 216, 202, 3, 212, 62, 72, 202, 213,
+ 202, 198, 141, 207, 60, 183, 126, 126, 62, 179,
+ 59, 163, 116, 60, 187, 66, 103, 60, 60, 198,
+ 104, 60, 189, 62, 190, 146, 189, 67, 126, 133,
+ 131, 132, 60, 72, 68, 60, 60, 59, 68, 62,
+ 72, 202, 68, 62, 49, 202, 62, 198, 59, 59,
+ 202, 210, 211, 68, 194, 60, 179, 119, 163, 5,
+ 65, 66, 75, 183, 198, 198, 68, 68, 95, 60,
+ 68, 130, 210, 195, 209, 202, 198, 208, 212, 195,
+ 195, 60, 14, 117, 120, 126, 126, 189, 60, 60,
+ 60, 60, 163, 20, 100, 66, 66, 68, 210, 210,
+ 118, 112, 105
};
#define yyerrok (yyerrstatus = 0)
@@ -1567,18 +1565,9 @@ static const yytype_uint8 yystos[] =
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
+ Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
#define YYRECOVERING() (!!yyerrstatus)
@@ -1588,6 +1577,7 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@@ -1629,10 +1619,19 @@ while (YYID (0))
#endif
-/* This macro is provided for backward compatibility. */
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
#endif
@@ -1736,20 +1735,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (; yybottom <= yytop; yybottom++)
- {
- int yybot = *yybottom;
- YYFPRINTF (stderr, " %d", yybot);
- }
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -1783,11 +1779,11 @@ yy_reduce_print (yyvsp, yyrule)
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ fprintf (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
);
- YYFPRINTF (stderr, "\n");
+ fprintf (stderr, "\n");
}
}
@@ -1824,6 +1820,7 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
+
#if YYERROR_VERBOSE
@@ -1926,142 +1923,115 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
- about the unexpected token YYTOKEN for the state stack whose top is
- YYSSP.
-
- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
- not large enough to hold the message. In that case, also set
- *YYMSG_ALLOC to the required number of bytes. Return 2 if the
- required number of bytes is too large to store. */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
- yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- /* Internationalized format string. */
- const char *yyformat = 0;
- /* Arguments of yyformat. */
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
- int yycount = 0;
-
- /* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- - If this state is a consistent state with a default action, then
- the only way this function was invoked is if the default action
- is an error action. In that case, don't check for expected
- tokens because there are none.
- - The only way there can be no lookahead present (in yychar) is if
- this state is a consistent state with a default action. Thus,
- detecting the absence of a lookahead is sufficient to determine
- that there is no unexpected or expected token to report. In that
- case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this state is a
- consistent state with a default action. There might have been a
- previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.
- - Of course, the expected token list depends on states to have
- correct lookahead information, and it depends on the parser not
- to perform extra reductions after fetching a lookahead from the
- scanner and before detecting a syntax error. Thus, state merging
- (from LALR or IELR) and default reductions corrupt the expected
- token list. However, the list is correct for canonical LR with
- one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.
- */
- if (yytoken != YYEMPTY)
- {
- int yyn = yypact[*yyssp];
- yyarg[yycount++] = yytname[yytoken];
- if (!yypact_value_is_default (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for
- this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
- && !yytable_value_is_error (yytable[yyx + yyn]))
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
- }
- }
- }
+ int yyn = yypact[yystate];
- switch (yycount)
- {
-# define YYCASE_(N, S) \
- case N: \
- yyformat = S; \
- break
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
- }
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
- if (*yymsg_alloc < yysize)
- {
- *yymsg_alloc = 2 * yysize;
- if (! (yysize <= *yymsg_alloc
- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
- return 1;
- }
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- {
- char *yyp = *yymsg;
- int yyi = 0;
- while ((*yyp = *yyformat) != '\0')
- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyformat += 2;
- }
- else
- {
- yyp++;
- yyformat++;
- }
- }
- return 0;
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
}
#endif /* YYERROR_VERBOSE */
+
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@@ -2093,9 +2063,10 @@ yydestruct (yymsg, yytype, yyvaluep)
break;
}
}
-
+
/* Prevent warnings from -Wmissing-prototypes. */
+
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
@@ -2111,16 +2082,18 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
-/* The lookahead symbol. */
+
+/* The look-ahead symbol. */
int yychar, yystate;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
int yynerrs;
+
/*----------.
| yyparse. |
`----------*/
@@ -2147,36 +2120,13 @@ yyparse ()
#endif
#endif
{
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
-
- /* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs;
- YYSTYPE *yyvsp;
-
- YYSIZE_T yystacksize;
-
+
int yyn;
int yyresult;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken;
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
@@ -2184,28 +2134,51 @@ yyparse ()
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
- yystacksize = YYINITDEPTH;
-
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
+ yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
+
yyssp = yyss;
yyvsp = yyvs;
@@ -2235,6 +2208,7 @@ yyparse ()
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
+
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
@@ -2242,6 +2216,7 @@ yyparse ()
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
+
&yystacksize);
yyss = yyss1;
@@ -2264,8 +2239,9 @@ yyparse ()
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
@@ -2276,6 +2252,7 @@ yyparse ()
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
+
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
@@ -2285,9 +2262,6 @@ yyparse ()
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
- if (yystate == YYFINAL)
- YYACCEPT;
-
goto yybackup;
/*-----------.
@@ -2296,16 +2270,16 @@ yyparse ()
yybackup:
/* Do appropriate processing given the current state. Read a
- lookahead token if we need one and don't already have one. */
+ look-ahead token if we need one and don't already have one. */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
- if (yypact_value_is_default (yyn))
+ if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@@ -2331,22 +2305,26 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
- if (yytable_value_is_error (yyn))
- goto yyerrlab;
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
- /* Shift the lookahead token. */
+ /* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the shifted token. */
- yychar = YYEMPTY;
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
yystate = yyn;
*++yyvsp = yylval;
@@ -2386,8 +2364,6 @@ yyreduce:
switch (yyn)
{
case 2:
-
-/* Line 1806 of yacc.c */
#line 128 "go.y"
{
xtop = concat(xtop, (yyvsp[(4) - (4)].list));
@@ -2395,8 +2371,6 @@ yyreduce:
break;
case 3:
-
-/* Line 1806 of yacc.c */
#line 134 "go.y"
{
prevlineno = lineno;
@@ -2407,8 +2381,6 @@ yyreduce:
break;
case 4:
-
-/* Line 1806 of yacc.c */
#line 141 "go.y"
{
mkpackage((yyvsp[(2) - (3)].sym)->name);
@@ -2416,8 +2388,6 @@ yyreduce:
break;
case 5:
-
-/* Line 1806 of yacc.c */
#line 151 "go.y"
{
importpkg = runtimepkg;
@@ -2431,8 +2401,6 @@ yyreduce:
break;
case 6:
-
-/* Line 1806 of yacc.c */
#line 162 "go.y"
{
importpkg = nil;
@@ -2440,8 +2408,6 @@ yyreduce:
break;
case 12:
-
-/* Line 1806 of yacc.c */
#line 176 "go.y"
{
Pkg *ipkg;
@@ -2478,8 +2444,6 @@ yyreduce:
break;
case 13:
-
-/* Line 1806 of yacc.c */
#line 209 "go.y"
{
// When an invalid import path is passed to importfile,
@@ -2492,8 +2456,6 @@ yyreduce:
break;
case 16:
-
-/* Line 1806 of yacc.c */
#line 224 "go.y"
{
// import with original name
@@ -2504,8 +2466,6 @@ yyreduce:
break;
case 17:
-
-/* Line 1806 of yacc.c */
#line 231 "go.y"
{
// import with given name
@@ -2516,8 +2476,6 @@ yyreduce:
break;
case 18:
-
-/* Line 1806 of yacc.c */
#line 238 "go.y"
{
// import into my name space
@@ -2528,8 +2486,6 @@ yyreduce:
break;
case 19:
-
-/* Line 1806 of yacc.c */
#line 247 "go.y"
{
if(importpkg->name == nil) {
@@ -2545,8 +2501,6 @@ yyreduce:
break;
case 21:
-
-/* Line 1806 of yacc.c */
#line 261 "go.y"
{
if(strcmp((yyvsp[(1) - (1)].sym)->name, "safe") == 0)
@@ -2555,8 +2509,6 @@ yyreduce:
break;
case 22:
-
-/* Line 1806 of yacc.c */
#line 267 "go.y"
{
defercheckwidth();
@@ -2564,8 +2516,6 @@ yyreduce:
break;
case 23:
-
-/* Line 1806 of yacc.c */
#line 271 "go.y"
{
resumecheckwidth();
@@ -2574,8 +2524,6 @@ yyreduce:
break;
case 24:
-
-/* Line 1806 of yacc.c */
#line 280 "go.y"
{
yyerror("empty top-level declaration");
@@ -2584,8 +2532,6 @@ yyreduce:
break;
case 26:
-
-/* Line 1806 of yacc.c */
#line 286 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
@@ -2593,8 +2539,6 @@ yyreduce:
break;
case 27:
-
-/* Line 1806 of yacc.c */
#line 290 "go.y"
{
yyerror("non-declaration statement outside function body");
@@ -2603,8 +2547,6 @@ yyreduce:
break;
case 28:
-
-/* Line 1806 of yacc.c */
#line 295 "go.y"
{
(yyval.list) = nil;
@@ -2612,8 +2554,6 @@ yyreduce:
break;
case 29:
-
-/* Line 1806 of yacc.c */
#line 301 "go.y"
{
(yyval.list) = (yyvsp[(2) - (2)].list);
@@ -2621,8 +2561,6 @@ yyreduce:
break;
case 30:
-
-/* Line 1806 of yacc.c */
#line 305 "go.y"
{
(yyval.list) = (yyvsp[(3) - (5)].list);
@@ -2630,8 +2568,6 @@ yyreduce:
break;
case 31:
-
-/* Line 1806 of yacc.c */
#line 309 "go.y"
{
(yyval.list) = nil;
@@ -2639,8 +2575,6 @@ yyreduce:
break;
case 32:
-
-/* Line 1806 of yacc.c */
#line 313 "go.y"
{
(yyval.list) = (yyvsp[(2) - (2)].list);
@@ -2650,8 +2584,6 @@ yyreduce:
break;
case 33:
-
-/* Line 1806 of yacc.c */
#line 319 "go.y"
{
(yyval.list) = (yyvsp[(3) - (5)].list);
@@ -2661,8 +2593,6 @@ yyreduce:
break;
case 34:
-
-/* Line 1806 of yacc.c */
#line 325 "go.y"
{
(yyval.list) = concat((yyvsp[(3) - (7)].list), (yyvsp[(5) - (7)].list));
@@ -2672,8 +2602,6 @@ yyreduce:
break;
case 35:
-
-/* Line 1806 of yacc.c */
#line 331 "go.y"
{
(yyval.list) = nil;
@@ -2682,8 +2610,6 @@ yyreduce:
break;
case 36:
-
-/* Line 1806 of yacc.c */
#line 336 "go.y"
{
(yyval.list) = list1((yyvsp[(2) - (2)].node));
@@ -2691,8 +2617,6 @@ yyreduce:
break;
case 37:
-
-/* Line 1806 of yacc.c */
#line 340 "go.y"
{
(yyval.list) = (yyvsp[(3) - (5)].list);
@@ -2700,8 +2624,6 @@ yyreduce:
break;
case 38:
-
-/* Line 1806 of yacc.c */
#line 344 "go.y"
{
(yyval.list) = nil;
@@ -2709,8 +2631,6 @@ yyreduce:
break;
case 39:
-
-/* Line 1806 of yacc.c */
#line 350 "go.y"
{
iota = 0;
@@ -2718,8 +2638,6 @@ yyreduce:
break;
case 40:
-
-/* Line 1806 of yacc.c */
#line 356 "go.y"
{
(yyval.list) = variter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
@@ -2727,8 +2645,6 @@ yyreduce:
break;
case 41:
-
-/* Line 1806 of yacc.c */
#line 360 "go.y"
{
(yyval.list) = variter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
@@ -2736,8 +2652,6 @@ yyreduce:
break;
case 42:
-
-/* Line 1806 of yacc.c */
#line 364 "go.y"
{
(yyval.list) = variter((yyvsp[(1) - (3)].list), nil, (yyvsp[(3) - (3)].list));
@@ -2745,8 +2659,6 @@ yyreduce:
break;
case 43:
-
-/* Line 1806 of yacc.c */
#line 370 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
@@ -2754,8 +2666,6 @@ yyreduce:
break;
case 44:
-
-/* Line 1806 of yacc.c */
#line 374 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (3)].list), N, (yyvsp[(3) - (3)].list));
@@ -2763,8 +2673,6 @@ yyreduce:
break;
case 46:
-
-/* Line 1806 of yacc.c */
#line 381 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
@@ -2772,8 +2680,6 @@ yyreduce:
break;
case 47:
-
-/* Line 1806 of yacc.c */
#line 385 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (1)].list), N, nil);
@@ -2781,8 +2687,6 @@ yyreduce:
break;
case 48:
-
-/* Line 1806 of yacc.c */
#line 391 "go.y"
{
// different from dclname because the name
@@ -2793,8 +2697,6 @@ yyreduce:
break;
case 49:
-
-/* Line 1806 of yacc.c */
#line 400 "go.y"
{
(yyval.node) = typedcl1((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node), 1);
@@ -2802,18 +2704,28 @@ yyreduce:
break;
case 50:
-
-/* Line 1806 of yacc.c */
#line 406 "go.y"
{
(yyval.node) = (yyvsp[(1) - (1)].node);
+
+ // These nodes do not carry line numbers.
+ // Since a bare name used as an expression is an error,
+ // introduce a wrapper node to give the correct line.
+ switch((yyval.node)->op) {
+ case ONAME:
+ case ONONAME:
+ case OTYPE:
+ case OPACK:
+ case OLITERAL:
+ (yyval.node) = nod(OPAREN, (yyval.node), N);
+ (yyval.node)->implicit = 1;
+ break;
+ }
}
break;
case 51:
-
-/* Line 1806 of yacc.c */
-#line 410 "go.y"
+#line 424 "go.y"
{
(yyval.node) = nod(OASOP, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
(yyval.node)->etype = (yyvsp[(2) - (3)].i); // rathole to pass opcode
@@ -2821,9 +2733,7 @@ yyreduce:
break;
case 52:
-
-/* Line 1806 of yacc.c */
-#line 415 "go.y"
+#line 429 "go.y"
{
if((yyvsp[(1) - (3)].list)->next == nil && (yyvsp[(3) - (3)].list)->next == nil) {
// simple
@@ -2838,9 +2748,7 @@ yyreduce:
break;
case 53:
-
-/* Line 1806 of yacc.c */
-#line 427 "go.y"
+#line 441 "go.y"
{
if((yyvsp[(3) - (3)].list)->n->op == OTYPESW) {
(yyval.node) = nod(OTYPESW, N, (yyvsp[(3) - (3)].list)->n->right);
@@ -2854,14 +2762,12 @@ yyreduce:
(yyval.node)->left = dclname((yyvsp[(1) - (3)].list)->n->sym); // it's a colas, so must not re-use an oldname.
break;
}
- (yyval.node) = colas((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
+ (yyval.node) = colas((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list), (yyvsp[(2) - (3)].i));
}
break;
case 54:
-
-/* Line 1806 of yacc.c */
-#line 443 "go.y"
+#line 457 "go.y"
{
(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
(yyval.node)->etype = OADD;
@@ -2869,9 +2775,7 @@ yyreduce:
break;
case 55:
-
-/* Line 1806 of yacc.c */
-#line 448 "go.y"
+#line 462 "go.y"
{
(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
(yyval.node)->etype = OSUB;
@@ -2879,9 +2783,7 @@ yyreduce:
break;
case 56:
-
-/* Line 1806 of yacc.c */
-#line 455 "go.y"
+#line 469 "go.y"
{
Node *n, *nn;
@@ -2904,9 +2806,7 @@ yyreduce:
break;
case 57:
-
-/* Line 1806 of yacc.c */
-#line 475 "go.y"
+#line 489 "go.y"
{
Node *n;
@@ -2927,23 +2827,19 @@ yyreduce:
break;
case 58:
-
-/* Line 1806 of yacc.c */
-#line 493 "go.y"
+#line 507 "go.y"
{
// will be converted to OCASE
// right will point to next case
// done in casebody()
markdcl();
(yyval.node) = nod(OXCASE, N, N);
- (yyval.node)->list = list1(colas((yyvsp[(2) - (5)].list), list1((yyvsp[(4) - (5)].node))));
+ (yyval.node)->list = list1(colas((yyvsp[(2) - (5)].list), list1((yyvsp[(4) - (5)].node)), (yyvsp[(3) - (5)].i)));
}
break;
case 59:
-
-/* Line 1806 of yacc.c */
-#line 502 "go.y"
+#line 516 "go.y"
{
Node *n, *nn;
@@ -2962,18 +2858,14 @@ yyreduce:
break;
case 60:
-
-/* Line 1806 of yacc.c */
-#line 520 "go.y"
+#line 534 "go.y"
{
markdcl();
}
break;
case 61:
-
-/* Line 1806 of yacc.c */
-#line 524 "go.y"
+#line 538 "go.y"
{
(yyval.node) = liststmt((yyvsp[(3) - (4)].list));
popdcl();
@@ -2981,9 +2873,7 @@ yyreduce:
break;
case 62:
-
-/* Line 1806 of yacc.c */
-#line 531 "go.y"
+#line 545 "go.y"
{
// If the last token read by the lexer was consumed
// as part of the case, clear it (parser has cleared yychar).
@@ -2996,9 +2886,7 @@ yyreduce:
break;
case 63:
-
-/* Line 1806 of yacc.c */
-#line 541 "go.y"
+#line 555 "go.y"
{
int last;
@@ -3020,36 +2908,28 @@ yyreduce:
break;
case 64:
-
-/* Line 1806 of yacc.c */
-#line 561 "go.y"
+#line 575 "go.y"
{
(yyval.list) = nil;
}
break;
case 65:
-
-/* Line 1806 of yacc.c */
-#line 565 "go.y"
+#line 579 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
}
break;
case 66:
-
-/* Line 1806 of yacc.c */
-#line 571 "go.y"
+#line 585 "go.y"
{
markdcl();
}
break;
case 67:
-
-/* Line 1806 of yacc.c */
-#line 575 "go.y"
+#line 589 "go.y"
{
(yyval.list) = (yyvsp[(3) - (4)].list);
popdcl();
@@ -3057,9 +2937,7 @@ yyreduce:
break;
case 68:
-
-/* Line 1806 of yacc.c */
-#line 582 "go.y"
+#line 596 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -3068,9 +2946,7 @@ yyreduce:
break;
case 69:
-
-/* Line 1806 of yacc.c */
-#line 588 "go.y"
+#line 602 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -3080,9 +2956,7 @@ yyreduce:
break;
case 70:
-
-/* Line 1806 of yacc.c */
-#line 597 "go.y"
+#line 611 "go.y"
{
// init ; test ; incr
if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0)
@@ -3096,9 +2970,7 @@ yyreduce:
break;
case 71:
-
-/* Line 1806 of yacc.c */
-#line 608 "go.y"
+#line 622 "go.y"
{
// normal test
(yyval.node) = nod(OFOR, N, N);
@@ -3107,9 +2979,7 @@ yyreduce:
break;
case 73:
-
-/* Line 1806 of yacc.c */
-#line 617 "go.y"
+#line 631 "go.y"
{
(yyval.node) = (yyvsp[(1) - (2)].node);
(yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list));
@@ -3117,18 +2987,14 @@ yyreduce:
break;
case 74:
-
-/* Line 1806 of yacc.c */
-#line 624 "go.y"
+#line 638 "go.y"
{
markdcl();
}
break;
case 75:
-
-/* Line 1806 of yacc.c */
-#line 628 "go.y"
+#line 642 "go.y"
{
(yyval.node) = (yyvsp[(3) - (3)].node);
popdcl();
@@ -3136,9 +3002,7 @@ yyreduce:
break;
case 76:
-
-/* Line 1806 of yacc.c */
-#line 635 "go.y"
+#line 649 "go.y"
{
// test
(yyval.node) = nod(OIF, N, N);
@@ -3147,9 +3011,7 @@ yyreduce:
break;
case 77:
-
-/* Line 1806 of yacc.c */
-#line 641 "go.y"
+#line 655 "go.y"
{
// init ; test
(yyval.node) = nod(OIF, N, N);
@@ -3160,18 +3022,14 @@ yyreduce:
break;
case 78:
-
-/* Line 1806 of yacc.c */
-#line 652 "go.y"
+#line 666 "go.y"
{
markdcl();
}
break;
case 79:
-
-/* Line 1806 of yacc.c */
-#line 656 "go.y"
+#line 670 "go.y"
{
if((yyvsp[(3) - (3)].node)->ntest == N)
yyerror("missing condition in if statement");
@@ -3179,66 +3037,89 @@ yyreduce:
break;
case 80:
-
-/* Line 1806 of yacc.c */
-#line 661 "go.y"
+#line 675 "go.y"
{
(yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
}
break;
case 81:
-
-/* Line 1806 of yacc.c */
-#line 665 "go.y"
+#line 679 "go.y"
{
+ Node *n;
+ NodeList *nn;
+
+ (yyval.node) = (yyvsp[(3) - (8)].node);
+ n = (yyvsp[(3) - (8)].node);
popdcl();
- (yyval.node) = (yyvsp[(3) - (7)].node);
- if((yyvsp[(7) - (7)].node) != N)
- (yyval.node)->nelse = list1((yyvsp[(7) - (7)].node));
+ for(nn = concat((yyvsp[(7) - (8)].list), (yyvsp[(8) - (8)].list)); nn; nn = nn->next) {
+ if(nn->n->op == OIF)
+ popdcl();
+ n->nelse = list1(nn->n);
+ n = nn->n;
+ }
}
break;
case 82:
-
-/* Line 1806 of yacc.c */
-#line 673 "go.y"
+#line 696 "go.y"
{
- (yyval.node) = N;
+ markdcl();
}
break;
case 83:
-
-/* Line 1806 of yacc.c */
-#line 677 "go.y"
+#line 700 "go.y"
{
- (yyval.node) = (yyvsp[(2) - (2)].node);
+ if((yyvsp[(4) - (5)].node)->ntest == N)
+ yyerror("missing condition in if statement");
+ (yyvsp[(4) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
+ (yyval.list) = list1((yyvsp[(4) - (5)].node));
}
break;
case 84:
-
-/* Line 1806 of yacc.c */
-#line 681 "go.y"
+#line 708 "go.y"
{
- (yyval.node) = (yyvsp[(2) - (2)].node);
+ (yyval.list) = nil;
}
break;
case 85:
-
-/* Line 1806 of yacc.c */
-#line 687 "go.y"
+#line 712 "go.y"
{
- markdcl();
+ (yyval.list) = concat((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list));
}
break;
case 86:
+#line 717 "go.y"
+ {
+ (yyval.list) = nil;
+ }
+ break;
+
+ case 87:
+#line 721 "go.y"
+ {
+ NodeList *node;
+
+ node = mal(sizeof *node);
+ node->n = (yyvsp[(2) - (2)].node);
+ node->end = node;
+ (yyval.list) = node;
+ }
+ break;
+
+ case 88:
+#line 732 "go.y"
+ {
+ markdcl();
+ }
+ break;
-/* Line 1806 of yacc.c */
-#line 691 "go.y"
+ case 89:
+#line 736 "go.y"
{
Node *n;
n = (yyvsp[(3) - (3)].node)->ntest;
@@ -3248,10 +3129,8 @@ yyreduce:
}
break;
- case 87:
-
-/* Line 1806 of yacc.c */
-#line 699 "go.y"
+ case 90:
+#line 744 "go.y"
{
(yyval.node) = (yyvsp[(3) - (7)].node);
(yyval.node)->op = OSWITCH;
@@ -3261,19 +3140,15 @@ yyreduce:
}
break;
- case 88:
-
-/* Line 1806 of yacc.c */
-#line 709 "go.y"
+ case 91:
+#line 754 "go.y"
{
typesw = nod(OXXX, typesw, N);
}
break;
- case 89:
-
-/* Line 1806 of yacc.c */
-#line 713 "go.y"
+ case 92:
+#line 758 "go.y"
{
(yyval.node) = nod(OSELECT, N, N);
(yyval.node)->lineno = typesw->lineno;
@@ -3282,199 +3157,155 @@ yyreduce:
}
break;
- case 91:
-
-/* Line 1806 of yacc.c */
-#line 726 "go.y"
+ case 94:
+#line 771 "go.y"
{
(yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 92:
-
-/* Line 1806 of yacc.c */
-#line 730 "go.y"
+ case 95:
+#line 775 "go.y"
{
(yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 93:
-
-/* Line 1806 of yacc.c */
-#line 734 "go.y"
+ case 96:
+#line 779 "go.y"
{
(yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 94:
-
-/* Line 1806 of yacc.c */
-#line 738 "go.y"
+ case 97:
+#line 783 "go.y"
{
(yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 95:
-
-/* Line 1806 of yacc.c */
-#line 742 "go.y"
+ case 98:
+#line 787 "go.y"
{
(yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 96:
-
-/* Line 1806 of yacc.c */
-#line 746 "go.y"
+ case 99:
+#line 791 "go.y"
{
(yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 97:
-
-/* Line 1806 of yacc.c */
-#line 750 "go.y"
+ case 100:
+#line 795 "go.y"
{
(yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 98:
-
-/* Line 1806 of yacc.c */
-#line 754 "go.y"
+ case 101:
+#line 799 "go.y"
{
(yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 99:
-
-/* Line 1806 of yacc.c */
-#line 758 "go.y"
+ case 102:
+#line 803 "go.y"
{
(yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 100:
-
-/* Line 1806 of yacc.c */
-#line 762 "go.y"
+ case 103:
+#line 807 "go.y"
{
(yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 101:
-
-/* Line 1806 of yacc.c */
-#line 766 "go.y"
+ case 104:
+#line 811 "go.y"
{
(yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 102:
-
-/* Line 1806 of yacc.c */
-#line 770 "go.y"
+ case 105:
+#line 815 "go.y"
{
(yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 103:
-
-/* Line 1806 of yacc.c */
-#line 774 "go.y"
+ case 106:
+#line 819 "go.y"
{
(yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 104:
-
-/* Line 1806 of yacc.c */
-#line 778 "go.y"
+ case 107:
+#line 823 "go.y"
{
(yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 105:
-
-/* Line 1806 of yacc.c */
-#line 782 "go.y"
+ case 108:
+#line 827 "go.y"
{
(yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 106:
-
-/* Line 1806 of yacc.c */
-#line 786 "go.y"
+ case 109:
+#line 831 "go.y"
{
(yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 107:
-
-/* Line 1806 of yacc.c */
-#line 790 "go.y"
+ case 110:
+#line 835 "go.y"
{
(yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 108:
-
-/* Line 1806 of yacc.c */
-#line 794 "go.y"
+ case 111:
+#line 839 "go.y"
{
(yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 109:
-
-/* Line 1806 of yacc.c */
-#line 798 "go.y"
+ case 112:
+#line 843 "go.y"
{
(yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 110:
-
-/* Line 1806 of yacc.c */
-#line 803 "go.y"
+ case 113:
+#line 848 "go.y"
{
(yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 112:
-
-/* Line 1806 of yacc.c */
-#line 810 "go.y"
+ case 115:
+#line 855 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
- case 113:
-
-/* Line 1806 of yacc.c */
-#line 814 "go.y"
+ case 116:
+#line 859 "go.y"
{
if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) {
// Special case for &T{...}: turn into (*T){...}.
@@ -3487,84 +3318,66 @@ yyreduce:
}
break;
- case 114:
-
-/* Line 1806 of yacc.c */
-#line 825 "go.y"
+ case 117:
+#line 870 "go.y"
{
(yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N);
}
break;
- case 115:
-
-/* Line 1806 of yacc.c */
-#line 829 "go.y"
+ case 118:
+#line 874 "go.y"
{
(yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N);
}
break;
- case 116:
-
-/* Line 1806 of yacc.c */
-#line 833 "go.y"
+ case 119:
+#line 878 "go.y"
{
(yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N);
}
break;
- case 117:
-
-/* Line 1806 of yacc.c */
-#line 837 "go.y"
+ case 120:
+#line 882 "go.y"
{
yyerror("the bitwise complement operator is ^");
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
}
break;
- case 118:
-
-/* Line 1806 of yacc.c */
-#line 842 "go.y"
+ case 121:
+#line 887 "go.y"
{
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
}
break;
- case 119:
-
-/* Line 1806 of yacc.c */
-#line 846 "go.y"
+ case 122:
+#line 891 "go.y"
{
(yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N);
}
break;
- case 120:
-
-/* Line 1806 of yacc.c */
-#line 856 "go.y"
+ case 123:
+#line 901 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N);
}
break;
- case 121:
-
-/* Line 1806 of yacc.c */
-#line 860 "go.y"
+ case 124:
+#line 905 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
}
break;
- case 122:
-
-/* Line 1806 of yacc.c */
-#line 865 "go.y"
+ case 125:
+#line 910 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N);
(yyval.node)->list = (yyvsp[(3) - (6)].list);
@@ -3572,19 +3385,15 @@ yyreduce:
}
break;
- case 123:
-
-/* Line 1806 of yacc.c */
-#line 873 "go.y"
+ case 126:
+#line 918 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
- case 125:
-
-/* Line 1806 of yacc.c */
-#line 878 "go.y"
+ case 128:
+#line 923 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
@@ -3597,57 +3406,45 @@ yyreduce:
}
break;
- case 126:
-
-/* Line 1806 of yacc.c */
-#line 889 "go.y"
+ case 129:
+#line 934 "go.y"
{
(yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node));
}
break;
- case 127:
-
-/* Line 1806 of yacc.c */
-#line 893 "go.y"
+ case 130:
+#line 938 "go.y"
{
(yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node));
}
break;
- case 128:
-
-/* Line 1806 of yacc.c */
-#line 897 "go.y"
+ case 131:
+#line 942 "go.y"
{
(yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
}
break;
- case 129:
-
-/* Line 1806 of yacc.c */
-#line 901 "go.y"
+ case 132:
+#line 946 "go.y"
{
(yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node)));
}
break;
- case 131:
-
-/* Line 1806 of yacc.c */
-#line 906 "go.y"
+ case 134:
+#line 951 "go.y"
{
// conversion
- (yyval.node) = nod(OCALL, (yyvsp[(1) - (4)].node), N);
- (yyval.node)->list = list1((yyvsp[(3) - (4)].node));
+ (yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
+ (yyval.node)->list = list1((yyvsp[(3) - (5)].node));
}
break;
- case 132:
-
-/* Line 1806 of yacc.c */
-#line 912 "go.y"
+ case 135:
+#line 957 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3656,10 +3453,8 @@ yyreduce:
}
break;
- case 133:
-
-/* Line 1806 of yacc.c */
-#line 919 "go.y"
+ case 136:
+#line 964 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3667,10 +3462,8 @@ yyreduce:
}
break;
- case 134:
-
-/* Line 1806 of yacc.c */
-#line 925 "go.y"
+ case 137:
+#line 970 "go.y"
{
yyerror("cannot parenthesize type in composite literal");
(yyval.node) = (yyvsp[(5) - (7)].node);
@@ -3679,10 +3472,8 @@ yyreduce:
}
break;
- case 136:
-
-/* Line 1806 of yacc.c */
-#line 934 "go.y"
+ case 139:
+#line 979 "go.y"
{
// composite expression.
// make node early so we get the right line number.
@@ -3690,29 +3481,51 @@ yyreduce:
}
break;
- case 137:
-
-/* Line 1806 of yacc.c */
-#line 942 "go.y"
+ case 140:
+#line 987 "go.y"
{
(yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 139:
+ case 141:
+#line 993 "go.y"
+ {
+ // These nodes do not carry line numbers.
+ // Since a composite literal commonly spans several lines,
+ // the line number on errors may be misleading.
+ // Introduce a wrapper node to give the correct line.
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ switch((yyval.node)->op) {
+ case ONAME:
+ case ONONAME:
+ case OTYPE:
+ case OPACK:
+ case OLITERAL:
+ (yyval.node) = nod(OPAREN, (yyval.node), N);
+ (yyval.node)->implicit = 1;
+ }
+ }
+ break;
-/* Line 1806 of yacc.c */
-#line 949 "go.y"
+ case 142:
+#line 1010 "go.y"
{
(yyval.node) = (yyvsp[(2) - (4)].node);
(yyval.node)->list = (yyvsp[(3) - (4)].list);
}
break;
- case 141:
+ case 144:
+#line 1018 "go.y"
+ {
+ (yyval.node) = (yyvsp[(2) - (4)].node);
+ (yyval.node)->list = (yyvsp[(3) - (4)].list);
+ }
+ break;
-/* Line 1806 of yacc.c */
-#line 957 "go.y"
+ case 146:
+#line 1026 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
@@ -3725,33 +3538,28 @@ yyreduce:
case OPACK:
case OTYPE:
case OLITERAL:
+ case OTYPESW:
(yyval.node) = nod(OPAREN, (yyval.node), N);
}
}
break;
- case 145:
-
-/* Line 1806 of yacc.c */
-#line 982 "go.y"
+ case 150:
+#line 1052 "go.y"
{
(yyval.i) = LBODY;
}
break;
- case 146:
-
-/* Line 1806 of yacc.c */
-#line 986 "go.y"
+ case 151:
+#line 1056 "go.y"
{
(yyval.i) = '{';
}
break;
- case 147:
-
-/* Line 1806 of yacc.c */
-#line 997 "go.y"
+ case 152:
+#line 1067 "go.y"
{
if((yyvsp[(1) - (1)].sym) == S)
(yyval.node) = N;
@@ -3760,28 +3568,22 @@ yyreduce:
}
break;
- case 148:
-
-/* Line 1806 of yacc.c */
-#line 1006 "go.y"
+ case 153:
+#line 1076 "go.y"
{
(yyval.node) = dclname((yyvsp[(1) - (1)].sym));
}
break;
- case 149:
-
-/* Line 1806 of yacc.c */
-#line 1011 "go.y"
+ case 154:
+#line 1081 "go.y"
{
(yyval.node) = N;
}
break;
- case 151:
-
-/* Line 1806 of yacc.c */
-#line 1018 "go.y"
+ case 156:
+#line 1088 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
// during imports, unqualified non-exported identifiers are from builtinpkg
@@ -3790,31 +3592,31 @@ yyreduce:
}
break;
- case 153:
-
-/* Line 1806 of yacc.c */
-#line 1026 "go.y"
+ case 158:
+#line 1096 "go.y"
{
(yyval.sym) = S;
}
break;
- case 154:
-
-/* Line 1806 of yacc.c */
-#line 1032 "go.y"
+ case 159:
+#line 1102 "go.y"
{
+ Pkg *p;
+
if((yyvsp[(2) - (4)].val).u.sval->len == 0)
- (yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, importpkg);
- else
- (yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, mkpkg((yyvsp[(2) - (4)].val).u.sval));
+ p = importpkg;
+ else {
+ if(isbadimport((yyvsp[(2) - (4)].val).u.sval))
+ errorexit();
+ p = mkpkg((yyvsp[(2) - (4)].val).u.sval);
+ }
+ (yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, p);
}
break;
- case 155:
-
-/* Line 1806 of yacc.c */
-#line 1041 "go.y"
+ case 160:
+#line 1117 "go.y"
{
(yyval.node) = oldname((yyvsp[(1) - (1)].sym));
if((yyval.node)->pack != N)
@@ -3822,56 +3624,44 @@ yyreduce:
}
break;
- case 157:
-
-/* Line 1806 of yacc.c */
-#line 1061 "go.y"
+ case 162:
+#line 1137 "go.y"
{
yyerror("final argument in variadic function missing type");
(yyval.node) = nod(ODDD, typenod(typ(TINTER)), N);
}
break;
- case 158:
-
-/* Line 1806 of yacc.c */
-#line 1066 "go.y"
+ case 163:
+#line 1142 "go.y"
{
(yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N);
}
break;
- case 164:
-
-/* Line 1806 of yacc.c */
-#line 1077 "go.y"
+ case 169:
+#line 1153 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
- case 168:
-
-/* Line 1806 of yacc.c */
-#line 1086 "go.y"
+ case 173:
+#line 1162 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
- case 173:
-
-/* Line 1806 of yacc.c */
-#line 1096 "go.y"
+ case 178:
+#line 1172 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
- case 183:
-
-/* Line 1806 of yacc.c */
-#line 1117 "go.y"
+ case 188:
+#line 1193 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
@@ -3884,77 +3674,61 @@ yyreduce:
}
break;
- case 184:
-
-/* Line 1806 of yacc.c */
-#line 1130 "go.y"
+ case 189:
+#line 1206 "go.y"
{
(yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node));
}
break;
- case 185:
-
-/* Line 1806 of yacc.c */
-#line 1134 "go.y"
+ case 190:
+#line 1210 "go.y"
{
// array literal of nelem
(yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node));
}
break;
- case 186:
-
-/* Line 1806 of yacc.c */
-#line 1139 "go.y"
+ case 191:
+#line 1215 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N);
(yyval.node)->etype = Cboth;
}
break;
- case 187:
-
-/* Line 1806 of yacc.c */
-#line 1144 "go.y"
+ case 192:
+#line 1220 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Csend;
}
break;
- case 188:
-
-/* Line 1806 of yacc.c */
-#line 1149 "go.y"
+ case 193:
+#line 1225 "go.y"
{
(yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
}
break;
- case 191:
-
-/* Line 1806 of yacc.c */
-#line 1157 "go.y"
+ case 196:
+#line 1233 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
- case 192:
-
-/* Line 1806 of yacc.c */
-#line 1163 "go.y"
+ case 197:
+#line 1239 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Crecv;
}
break;
- case 193:
-
-/* Line 1806 of yacc.c */
-#line 1170 "go.y"
+ case 198:
+#line 1246 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3962,20 +3736,16 @@ yyreduce:
}
break;
- case 194:
-
-/* Line 1806 of yacc.c */
-#line 1176 "go.y"
+ case 199:
+#line 1252 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
}
break;
- case 195:
-
-/* Line 1806 of yacc.c */
-#line 1183 "go.y"
+ case 200:
+#line 1259 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3983,34 +3753,31 @@ yyreduce:
}
break;
- case 196:
-
-/* Line 1806 of yacc.c */
-#line 1189 "go.y"
+ case 201:
+#line 1265 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
}
break;
- case 197:
-
-/* Line 1806 of yacc.c */
-#line 1200 "go.y"
+ case 202:
+#line 1276 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
if((yyval.node) == N)
break;
+ if(noescape && (yyvsp[(3) - (3)].list) != nil)
+ yyerror("can only use //go:noescape with external func implementations");
(yyval.node)->nbody = (yyvsp[(3) - (3)].list);
(yyval.node)->endlineno = lineno;
+ (yyval.node)->noescape = noescape;
funcbody((yyval.node));
}
break;
- case 198:
-
-/* Line 1806 of yacc.c */
-#line 1211 "go.y"
+ case 203:
+#line 1290 "go.y"
{
Node *t;
@@ -4041,10 +3808,8 @@ yyreduce:
}
break;
- case 199:
-
-/* Line 1806 of yacc.c */
-#line 1240 "go.y"
+ case 204:
+#line 1319 "go.y"
{
Node *rcvr, *t;
@@ -4077,16 +3842,15 @@ yyreduce:
(yyval.node)->nname = methodname1((yyval.node)->shortname, rcvr->right);
(yyval.node)->nname->defn = (yyval.node);
(yyval.node)->nname->ntype = t;
+ (yyval.node)->nname->nointerface = nointerface;
declare((yyval.node)->nname, PFUNC);
funchdr((yyval.node));
}
break;
- case 200:
-
-/* Line 1806 of yacc.c */
-#line 1279 "go.y"
+ case 205:
+#line 1359 "go.y"
{
Sym *s;
Type *t;
@@ -4098,8 +3862,10 @@ yyreduce:
importsym(s, ONAME);
if(s->def != N && s->def->op == ONAME) {
- if(eqtype(t, s->def->type))
+ if(eqtype(t, s->def->type)) {
+ dclcontext = PDISCARD; // since we skip funchdr below
break;
+ }
yyerror("inconsistent definition for func %S during import\n\t%T\n\t%T", s, s->def->type, t);
}
@@ -4111,16 +3877,15 @@ yyreduce:
}
break;
- case 201:
-
-/* Line 1806 of yacc.c */
-#line 1302 "go.y"
+ case 206:
+#line 1384 "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));
checkwidth((yyval.node)->type);
- addmethod((yyvsp[(4) - (8)].sym), (yyval.node)->type, 0);
+ addmethod((yyvsp[(4) - (8)].sym), (yyval.node)->type, 0, nointerface);
+ nointerface = 0;
funchdr((yyval.node));
// inl.c's inlnode in on a dotmeth node expects to find the inlineable body as
@@ -4131,10 +3896,8 @@ yyreduce:
}
break;
- case 202:
-
-/* Line 1806 of yacc.c */
-#line 1319 "go.y"
+ case 207:
+#line 1402 "go.y"
{
(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
(yyval.node) = nod(OTFUNC, N, N);
@@ -4143,19 +3906,15 @@ yyreduce:
}
break;
- case 203:
-
-/* Line 1806 of yacc.c */
-#line 1327 "go.y"
+ case 208:
+#line 1410 "go.y"
{
(yyval.list) = nil;
}
break;
- case 204:
-
-/* Line 1806 of yacc.c */
-#line 1331 "go.y"
+ case 209:
+#line 1414 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
if((yyval.list) == nil)
@@ -4163,149 +3922,119 @@ yyreduce:
}
break;
- case 205:
-
-/* Line 1806 of yacc.c */
-#line 1339 "go.y"
+ case 210:
+#line 1422 "go.y"
{
(yyval.list) = nil;
}
break;
- case 206:
-
-/* Line 1806 of yacc.c */
-#line 1343 "go.y"
+ case 211:
+#line 1426 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
}
break;
- case 207:
-
-/* Line 1806 of yacc.c */
-#line 1347 "go.y"
+ case 212:
+#line 1430 "go.y"
{
(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
(yyval.list) = (yyvsp[(2) - (3)].list);
}
break;
- case 208:
-
-/* Line 1806 of yacc.c */
-#line 1354 "go.y"
+ case 213:
+#line 1437 "go.y"
{
closurehdr((yyvsp[(1) - (1)].node));
}
break;
- case 209:
-
-/* Line 1806 of yacc.c */
-#line 1360 "go.y"
+ case 214:
+#line 1443 "go.y"
{
(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
fixlbrace((yyvsp[(2) - (4)].i));
}
break;
- case 210:
-
-/* Line 1806 of yacc.c */
-#line 1365 "go.y"
+ case 215:
+#line 1448 "go.y"
{
(yyval.node) = closurebody(nil);
}
break;
- case 211:
-
-/* Line 1806 of yacc.c */
-#line 1376 "go.y"
+ case 216:
+#line 1459 "go.y"
{
(yyval.list) = nil;
}
break;
- case 212:
-
-/* Line 1806 of yacc.c */
-#line 1380 "go.y"
+ case 217:
+#line 1463 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
if(nsyntaxerrors == 0)
testdclstack();
+ nointerface = 0;
+ noescape = 0;
}
break;
- case 214:
-
-/* Line 1806 of yacc.c */
-#line 1389 "go.y"
+ case 219:
+#line 1474 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
- case 216:
-
-/* Line 1806 of yacc.c */
-#line 1396 "go.y"
+ case 221:
+#line 1481 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
- case 217:
-
-/* Line 1806 of yacc.c */
-#line 1402 "go.y"
+ case 222:
+#line 1487 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 218:
-
-/* Line 1806 of yacc.c */
-#line 1406 "go.y"
+ case 223:
+#line 1491 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 220:
-
-/* Line 1806 of yacc.c */
-#line 1413 "go.y"
+ case 225:
+#line 1498 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
- case 221:
-
-/* Line 1806 of yacc.c */
-#line 1419 "go.y"
+ case 226:
+#line 1504 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 222:
-
-/* Line 1806 of yacc.c */
-#line 1423 "go.y"
+ case 227:
+#line 1508 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 223:
-
-/* Line 1806 of yacc.c */
-#line 1429 "go.y"
+ case 228:
+#line 1514 "go.y"
{
NodeList *l;
@@ -4330,20 +4059,16 @@ yyreduce:
}
break;
- case 224:
-
-/* Line 1806 of yacc.c */
-#line 1452 "go.y"
+ case 229:
+#line 1537 "go.y"
{
(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
(yyval.list) = list1((yyvsp[(1) - (2)].node));
}
break;
- case 225:
-
-/* Line 1806 of yacc.c */
-#line 1457 "go.y"
+ case 230:
+#line 1542 "go.y"
{
(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
(yyval.list) = list1((yyvsp[(2) - (4)].node));
@@ -4351,10 +4076,8 @@ yyreduce:
}
break;
- case 226:
-
-/* Line 1806 of yacc.c */
-#line 1463 "go.y"
+ case 231:
+#line 1548 "go.y"
{
(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
@@ -4362,10 +4085,8 @@ yyreduce:
}
break;
- case 227:
-
-/* Line 1806 of yacc.c */
-#line 1469 "go.y"
+ case 232:
+#line 1554 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4374,10 +4095,8 @@ yyreduce:
}
break;
- case 228:
-
-/* Line 1806 of yacc.c */
-#line 1476 "go.y"
+ case 233:
+#line 1561 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4386,10 +4105,8 @@ yyreduce:
}
break;
- case 229:
-
-/* Line 1806 of yacc.c */
-#line 1485 "go.y"
+ case 234:
+#line 1570 "go.y"
{
Node *n;
@@ -4400,10 +4117,8 @@ yyreduce:
}
break;
- case 230:
-
-/* Line 1806 of yacc.c */
-#line 1494 "go.y"
+ case 235:
+#line 1579 "go.y"
{
Pkg *pkg;
@@ -4418,48 +4133,38 @@ yyreduce:
}
break;
- case 231:
-
-/* Line 1806 of yacc.c */
-#line 1509 "go.y"
+ case 236:
+#line 1594 "go.y"
{
(yyval.node) = embedded((yyvsp[(1) - (1)].sym));
}
break;
- case 232:
-
-/* Line 1806 of yacc.c */
-#line 1515 "go.y"
+ case 237:
+#line 1600 "go.y"
{
(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
ifacedcl((yyval.node));
}
break;
- case 233:
-
-/* Line 1806 of yacc.c */
-#line 1520 "go.y"
+ case 238:
+#line 1605 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
}
break;
- case 234:
-
-/* Line 1806 of yacc.c */
-#line 1524 "go.y"
+ case 239:
+#line 1609 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
yyerror("cannot parenthesize embedded type");
}
break;
- case 235:
-
-/* Line 1806 of yacc.c */
-#line 1531 "go.y"
+ case 240:
+#line 1616 "go.y"
{
// without func keyword
(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
@@ -4469,10 +4174,8 @@ yyreduce:
}
break;
- case 237:
-
-/* Line 1806 of yacc.c */
-#line 1545 "go.y"
+ case 242:
+#line 1630 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4480,10 +4183,8 @@ yyreduce:
}
break;
- case 238:
-
-/* Line 1806 of yacc.c */
-#line 1551 "go.y"
+ case 243:
+#line 1636 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4491,83 +4192,65 @@ yyreduce:
}
break;
- case 240:
-
-/* Line 1806 of yacc.c */
-#line 1560 "go.y"
+ case 245:
+#line 1645 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 241:
-
-/* Line 1806 of yacc.c */
-#line 1564 "go.y"
+ case 246:
+#line 1649 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 242:
-
-/* Line 1806 of yacc.c */
-#line 1569 "go.y"
+ case 247:
+#line 1654 "go.y"
{
(yyval.list) = nil;
}
break;
- case 243:
-
-/* Line 1806 of yacc.c */
-#line 1573 "go.y"
+ case 248:
+#line 1658 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
- case 244:
-
-/* Line 1806 of yacc.c */
-#line 1581 "go.y"
+ case 249:
+#line 1666 "go.y"
{
(yyval.node) = N;
}
break;
- case 246:
-
-/* Line 1806 of yacc.c */
-#line 1586 "go.y"
+ case 251:
+#line 1671 "go.y"
{
(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
}
break;
- case 248:
-
-/* Line 1806 of yacc.c */
-#line 1591 "go.y"
+ case 253:
+#line 1676 "go.y"
{
(yyval.node) = N;
}
break;
- case 254:
-
-/* Line 1806 of yacc.c */
-#line 1602 "go.y"
+ case 259:
+#line 1687 "go.y"
{
(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
(yyvsp[(1) - (2)].node)->sym = dclstack; // context, for goto restrictions
}
break;
- case 255:
-
-/* Line 1806 of yacc.c */
-#line 1607 "go.y"
+ case 260:
+#line 1692 "go.y"
{
NodeList *l;
@@ -4579,66 +4262,52 @@ yyreduce:
}
break;
- case 256:
-
-/* Line 1806 of yacc.c */
-#line 1617 "go.y"
+ case 261:
+#line 1702 "go.y"
{
// will be converted to OFALL
(yyval.node) = nod(OXFALL, N, N);
}
break;
- case 257:
-
-/* Line 1806 of yacc.c */
-#line 1622 "go.y"
+ case 262:
+#line 1707 "go.y"
{
(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
}
break;
- case 258:
-
-/* Line 1806 of yacc.c */
-#line 1626 "go.y"
+ case 263:
+#line 1711 "go.y"
{
(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
}
break;
- case 259:
-
-/* Line 1806 of yacc.c */
-#line 1630 "go.y"
+ case 264:
+#line 1715 "go.y"
{
(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
}
break;
- case 260:
-
-/* Line 1806 of yacc.c */
-#line 1634 "go.y"
+ case 265:
+#line 1719 "go.y"
{
(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
}
break;
- case 261:
-
-/* Line 1806 of yacc.c */
-#line 1638 "go.y"
+ case 266:
+#line 1723 "go.y"
{
(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
(yyval.node)->sym = dclstack; // context, for goto restrictions
}
break;
- case 262:
-
-/* Line 1806 of yacc.c */
-#line 1643 "go.y"
+ case 267:
+#line 1728 "go.y"
{
(yyval.node) = nod(ORETURN, N, N);
(yyval.node)->list = (yyvsp[(2) - (2)].list);
@@ -4657,10 +4326,8 @@ yyreduce:
}
break;
- case 263:
-
-/* Line 1806 of yacc.c */
-#line 1662 "go.y"
+ case 268:
+#line 1747 "go.y"
{
(yyval.list) = nil;
if((yyvsp[(1) - (1)].node) != N)
@@ -4668,10 +4335,8 @@ yyreduce:
}
break;
- case 264:
-
-/* Line 1806 of yacc.c */
-#line 1668 "go.y"
+ case 269:
+#line 1753 "go.y"
{
(yyval.list) = (yyvsp[(1) - (3)].list);
if((yyvsp[(3) - (3)].node) != N)
@@ -4679,247 +4344,195 @@ yyreduce:
}
break;
- case 265:
-
-/* Line 1806 of yacc.c */
-#line 1676 "go.y"
+ case 270:
+#line 1761 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 266:
-
-/* Line 1806 of yacc.c */
-#line 1680 "go.y"
+ case 271:
+#line 1765 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 267:
-
-/* Line 1806 of yacc.c */
-#line 1686 "go.y"
+ case 272:
+#line 1771 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 268:
-
-/* Line 1806 of yacc.c */
-#line 1690 "go.y"
+ case 273:
+#line 1775 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 269:
-
-/* Line 1806 of yacc.c */
-#line 1696 "go.y"
+ case 274:
+#line 1781 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 270:
-
-/* Line 1806 of yacc.c */
-#line 1700 "go.y"
+ case 275:
+#line 1785 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 271:
-
-/* Line 1806 of yacc.c */
-#line 1706 "go.y"
+ case 276:
+#line 1791 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 272:
-
-/* Line 1806 of yacc.c */
-#line 1710 "go.y"
+ case 277:
+#line 1795 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 273:
-
-/* Line 1806 of yacc.c */
-#line 1719 "go.y"
+ case 278:
+#line 1804 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 274:
-
-/* Line 1806 of yacc.c */
-#line 1723 "go.y"
+ case 279:
+#line 1808 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 275:
-
-/* Line 1806 of yacc.c */
-#line 1727 "go.y"
+ case 280:
+#line 1812 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 276:
-
-/* Line 1806 of yacc.c */
-#line 1731 "go.y"
+ case 281:
+#line 1816 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 277:
-
-/* Line 1806 of yacc.c */
-#line 1736 "go.y"
+ case 282:
+#line 1821 "go.y"
{
(yyval.list) = nil;
}
break;
- case 278:
-
-/* Line 1806 of yacc.c */
-#line 1740 "go.y"
+ case 283:
+#line 1825 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
- case 283:
-
-/* Line 1806 of yacc.c */
-#line 1754 "go.y"
+ case 288:
+#line 1839 "go.y"
{
(yyval.node) = N;
}
break;
- case 285:
-
-/* Line 1806 of yacc.c */
-#line 1760 "go.y"
+ case 290:
+#line 1845 "go.y"
{
(yyval.list) = nil;
}
break;
- case 287:
-
-/* Line 1806 of yacc.c */
-#line 1766 "go.y"
+ case 292:
+#line 1851 "go.y"
{
(yyval.node) = N;
}
break;
- case 289:
-
-/* Line 1806 of yacc.c */
-#line 1772 "go.y"
+ case 294:
+#line 1857 "go.y"
{
(yyval.list) = nil;
}
break;
- case 291:
-
-/* Line 1806 of yacc.c */
-#line 1778 "go.y"
+ case 296:
+#line 1863 "go.y"
{
(yyval.list) = nil;
}
break;
- case 293:
-
-/* Line 1806 of yacc.c */
-#line 1784 "go.y"
+ case 298:
+#line 1869 "go.y"
{
(yyval.list) = nil;
}
break;
- case 295:
-
-/* Line 1806 of yacc.c */
-#line 1790 "go.y"
+ case 300:
+#line 1875 "go.y"
{
(yyval.val).ctype = CTxxx;
}
break;
- case 297:
-
-/* Line 1806 of yacc.c */
-#line 1800 "go.y"
+ case 302:
+#line 1885 "go.y"
{
importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
}
break;
- case 298:
-
-/* Line 1806 of yacc.c */
-#line 1804 "go.y"
+ case 303:
+#line 1889 "go.y"
{
importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
}
break;
- case 299:
-
-/* Line 1806 of yacc.c */
-#line 1808 "go.y"
+ case 304:
+#line 1893 "go.y"
{
importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
}
break;
- case 300:
-
-/* Line 1806 of yacc.c */
-#line 1812 "go.y"
+ case 305:
+#line 1897 "go.y"
{
importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
}
break;
- case 301:
-
-/* Line 1806 of yacc.c */
-#line 1816 "go.y"
+ case 306:
+#line 1901 "go.y"
{
importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
}
break;
- case 302:
-
-/* Line 1806 of yacc.c */
-#line 1820 "go.y"
+ case 307:
+#line 1905 "go.y"
{
- if((yyvsp[(2) - (4)].node) == N)
+ if((yyvsp[(2) - (4)].node) == N) {
+ dclcontext = PEXTERN; // since we skip the funcbody below
break;
+ }
(yyvsp[(2) - (4)].node)->inl = (yyvsp[(3) - (4)].list);
@@ -4928,45 +4541,37 @@ yyreduce:
if(debug['E']) {
print("import [%Z] func %lN \n", importpkg->path, (yyvsp[(2) - (4)].node));
- if(debug['l'] > 2 && (yyvsp[(2) - (4)].node)->inl)
+ if(debug['m'] > 2 && (yyvsp[(2) - (4)].node)->inl)
print("inl body:%+H\n", (yyvsp[(2) - (4)].node)->inl);
}
}
break;
- case 303:
-
-/* Line 1806 of yacc.c */
-#line 1838 "go.y"
+ case 308:
+#line 1925 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
structpkg = (yyval.sym)->pkg;
}
break;
- case 304:
-
-/* Line 1806 of yacc.c */
-#line 1845 "go.y"
+ case 309:
+#line 1932 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
importsym((yyvsp[(1) - (1)].sym), OTYPE);
}
break;
- case 310:
-
-/* Line 1806 of yacc.c */
-#line 1865 "go.y"
+ case 315:
+#line 1952 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
}
break;
- case 311:
-
-/* Line 1806 of yacc.c */
-#line 1869 "go.y"
+ case 316:
+#line 1956 "go.y"
{
// predefined name like uint8
(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
@@ -4978,64 +4583,50 @@ yyreduce:
}
break;
- case 312:
-
-/* Line 1806 of yacc.c */
-#line 1879 "go.y"
+ case 317:
+#line 1966 "go.y"
{
(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
}
break;
- case 313:
-
-/* Line 1806 of yacc.c */
-#line 1883 "go.y"
+ case 318:
+#line 1970 "go.y"
{
(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
}
break;
- case 314:
-
-/* Line 1806 of yacc.c */
-#line 1887 "go.y"
+ case 319:
+#line 1974 "go.y"
{
(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
}
break;
- case 315:
-
-/* Line 1806 of yacc.c */
-#line 1891 "go.y"
+ case 320:
+#line 1978 "go.y"
{
(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
}
break;
- case 316:
-
-/* Line 1806 of yacc.c */
-#line 1895 "go.y"
+ case 321:
+#line 1982 "go.y"
{
(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
}
break;
- case 317:
-
-/* Line 1806 of yacc.c */
-#line 1899 "go.y"
+ case 322:
+#line 1986 "go.y"
{
(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
}
break;
- case 318:
-
-/* Line 1806 of yacc.c */
-#line 1903 "go.y"
+ case 323:
+#line 1990 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(2) - (2)].type);
@@ -5043,10 +4634,8 @@ yyreduce:
}
break;
- case 319:
-
-/* Line 1806 of yacc.c */
-#line 1909 "go.y"
+ case 324:
+#line 1996 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (4)].type);
@@ -5054,10 +4643,8 @@ yyreduce:
}
break;
- case 320:
-
-/* Line 1806 of yacc.c */
-#line 1915 "go.y"
+ case 325:
+#line 2002 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -5065,10 +4652,8 @@ yyreduce:
}
break;
- case 321:
-
-/* Line 1806 of yacc.c */
-#line 1923 "go.y"
+ case 326:
+#line 2010 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -5076,19 +4661,15 @@ yyreduce:
}
break;
- case 322:
-
-/* Line 1806 of yacc.c */
-#line 1931 "go.y"
+ case 327:
+#line 2018 "go.y"
{
(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
}
break;
- case 323:
-
-/* Line 1806 of yacc.c */
-#line 1937 "go.y"
+ case 328:
+#line 2024 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
if((yyvsp[(1) - (3)].sym))
@@ -5097,10 +4678,8 @@ yyreduce:
}
break;
- case 324:
-
-/* Line 1806 of yacc.c */
-#line 1944 "go.y"
+ case 329:
+#line 2031 "go.y"
{
Type *t;
@@ -5116,10 +4695,8 @@ yyreduce:
}
break;
- case 325:
-
-/* Line 1806 of yacc.c */
-#line 1960 "go.y"
+ case 330:
+#line 2047 "go.y"
{
Sym *s;
@@ -5137,64 +4714,50 @@ yyreduce:
}
break;
- case 326:
-
-/* Line 1806 of yacc.c */
-#line 1978 "go.y"
+ case 331:
+#line 2065 "go.y"
{
(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list))));
}
break;
- case 327:
-
-/* Line 1806 of yacc.c */
-#line 1982 "go.y"
+ case 332:
+#line 2069 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
}
break;
- case 328:
-
-/* Line 1806 of yacc.c */
-#line 1987 "go.y"
+ case 333:
+#line 2074 "go.y"
{
(yyval.list) = nil;
}
break;
- case 330:
-
-/* Line 1806 of yacc.c */
-#line 1994 "go.y"
+ case 335:
+#line 2081 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
}
break;
- case 331:
-
-/* Line 1806 of yacc.c */
-#line 1998 "go.y"
+ case 336:
+#line 2085 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
}
break;
- case 332:
-
-/* Line 1806 of yacc.c */
-#line 2008 "go.y"
+ case 337:
+#line 2095 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
- case 333:
-
-/* Line 1806 of yacc.c */
-#line 2012 "go.y"
+ case 338:
+#line 2099 "go.y"
{
(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
switch((yyval.node)->val.ctype){
@@ -5211,10 +4774,8 @@ yyreduce:
}
break;
- case 334:
-
-/* Line 1806 of yacc.c */
-#line 2027 "go.y"
+ case 339:
+#line 2114 "go.y"
{
(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
if((yyval.node)->op != OLITERAL)
@@ -5222,91 +4783,67 @@ yyreduce:
}
break;
- case 336:
-
-/* Line 1806 of yacc.c */
-#line 2036 "go.y"
+ case 341:
+#line 2123 "go.y"
{
if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
(yyval.node) = (yyvsp[(2) - (5)].node);
mpaddfixfix((yyvsp[(2) - (5)].node)->val.u.xval, (yyvsp[(4) - (5)].node)->val.u.xval, 0);
break;
}
+ (yyvsp[(4) - (5)].node)->val.u.cval->real = (yyvsp[(4) - (5)].node)->val.u.cval->imag;
+ mpmovecflt(&(yyvsp[(4) - (5)].node)->val.u.cval->imag, 0.0);
(yyval.node) = nodcplxlit((yyvsp[(2) - (5)].node)->val, (yyvsp[(4) - (5)].node)->val);
}
break;
- case 339:
-
-/* Line 1806 of yacc.c */
-#line 2050 "go.y"
+ case 344:
+#line 2139 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 340:
-
-/* Line 1806 of yacc.c */
-#line 2054 "go.y"
+ case 345:
+#line 2143 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 341:
-
-/* Line 1806 of yacc.c */
-#line 2060 "go.y"
+ case 346:
+#line 2149 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 342:
-
-/* Line 1806 of yacc.c */
-#line 2064 "go.y"
+ case 347:
+#line 2153 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
- case 343:
-
-/* Line 1806 of yacc.c */
-#line 2070 "go.y"
+ case 348:
+#line 2159 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
- case 344:
-
-/* Line 1806 of yacc.c */
-#line 2074 "go.y"
+ case 349:
+#line 2163 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
-
-/* Line 1806 of yacc.c */
-#line 5298 "y.tab.c"
+/* Line 1267 of yacc.c. */
+#line 4846 "y.tab.c"
default: break;
}
- /* User semantic actions sometimes alter yychar, and that requires
- that yytoken be updated with the new translation. We take the
- approach of translating immediately before every use of yytoken.
- One alternative is translating here after every semantic action,
- but that translation would be missed if the semantic action invokes
- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
- incorrect destructor might then be invoked immediately. In the
- case of YYERROR or YYBACKUP, subsequent parser actions might lead
- to an incorrect destructor call or verbose syntax error message
- before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@@ -5315,6 +4852,7 @@ yyreduce:
*++yyvsp = yyval;
+
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
@@ -5334,10 +4872,6 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@@ -5345,36 +4879,37 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
- yyssp, yytoken)
{
- char *yymsgp = YY_("syntax error");
- int yysyntax_error_status;
- yysyntax_error_status = YYSYNTAX_ERROR;
- if (yysyntax_error_status == 0)
- yymsgp = yymsg;
- else if (yysyntax_error_status == 1)
- {
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
- if (!yymsg)
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- yysyntax_error_status = 2;
- }
- else
- {
- yysyntax_error_status = YYSYNTAX_ERROR;
- yymsgp = yymsg;
- }
- }
- yyerror (yymsgp);
- if (yysyntax_error_status == 2)
- goto yyexhaustedlab;
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
}
-# undef YYSYNTAX_ERROR
#endif
}
@@ -5382,7 +4917,7 @@ yyerrlab:
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
if (yychar <= YYEOF)
@@ -5399,7 +4934,7 @@ yyerrlab:
}
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
@@ -5433,7 +4968,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
- if (!yypact_value_is_default (yyn))
+ if (yyn != YYPACT_NINF)
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -5456,6 +4991,9 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
*++yyvsp = yylval;
@@ -5480,7 +5018,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#ifndef yyoverflow
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -5491,14 +5029,9 @@ yyexhaustedlab:
#endif
yyreturn:
- if (yychar != YYEMPTY)
- {
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = YYTRANSLATE (yychar);
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
- }
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
@@ -5522,9 +5055,7 @@ yyreturn:
}
-
-/* Line 2067 of yacc.c */
-#line 2078 "go.y"
+#line 2167 "go.y"
static void
diff --git a/src/cmd/gc/y.tab.h b/src/cmd/gc/y.tab.h
index bc6c47d6d..d01fbe198 100644
--- a/src/cmd/gc/y.tab.h
+++ b/src/cmd/gc/y.tab.h
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison interface for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -39,10 +41,10 @@
enum yytokentype {
LLITERAL = 258,
LASOP = 259,
- LBREAK = 260,
- LCASE = 261,
- LCHAN = 262,
- LCOLAS = 263,
+ LCOLAS = 260,
+ LBREAK = 261,
+ LCASE = 262,
+ LCHAN = 263,
LCONST = 264,
LCONTINUE = 265,
LDDD = 266,
@@ -91,10 +93,10 @@
/* Tokens. */
#define LLITERAL 258
#define LASOP 259
-#define LBREAK 260
-#define LCASE 261
-#define LCHAN 262
-#define LCOLAS 263
+#define LCOLAS 260
+#define LBREAK 261
+#define LCASE 262
+#define LCHAN 263
#define LCONST 264
#define LCONTINUE 265
#define LDDD 266
@@ -144,28 +146,22 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 2068 of yacc.c */
#line 28 "go.y"
-
+{
Node* node;
NodeList* list;
Type* type;
Sym* sym;
struct Val val;
int i;
-
-
-
-/* Line 2068 of yacc.c */
-#line 163 "y.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1529 of yacc.c. */
+#line 160 "y.tab.h"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;
-
diff --git a/src/cmd/gc/yerr.h b/src/cmd/gc/yerr.h
index 588890d0e..e7eb6516c 100644
--- a/src/cmd/gc/yerr.h
+++ b/src/cmd/gc/yerr.h
@@ -26,7 +26,7 @@ static struct {
237, ';',
"unexpected semicolon or newline before {",
- 474, LBODY,
+ 475, LBODY,
"unexpected semicolon or newline before {",
22, '{',
@@ -44,7 +44,7 @@ static struct {
37, ',',
"unexpected comma in channel type",
- 437, LELSE,
+ 438, LELSE,
"unexpected semicolon or newline before else",
257, ',',
@@ -65,9 +65,12 @@ static struct {
425, ';',
"need trailing comma before newline in composite literal",
+ 436, ';',
+ "need trailing comma before newline in composite literal",
+
112, LNAME,
"nested func not allowed",
- 615, ';',
+ 642, ';',
"else must be followed by if or statement block"
};