From: Ken Thompson Date: Thu, 23 Oct 2008 01:18:08 +0000 (-0700) Subject: embedded types X-Git-Tag: weekly.2009-11-06~2911 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7ed8fc611ddbb4c09784d81a52e5d59825677f42;p=gostls13.git embedded types auto & on methods R=r OCL=17682 CL=17682 --- diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 973b6f2c63..25e92bc9c3 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -584,6 +584,8 @@ int isinter(Type*); int isnilinter(Type*); Sym* globalsig(Type*); Type* ismethod(Type*); +Type* methtype(Type*); +int needaddr(Type*); Sym* signame(Type*, int); int bytearraysz(Type*); int eqtype(Type*, Type*, int); diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index d81c47c9f4..4e1a9ea3a3 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -1518,6 +1518,51 @@ out: return t; } +/* + * this is ismethod() without side effects + */ +Type* +methtype(Type *t) +{ + Sym *s; + + if(t == T) + return T; + if(t->etype == TINTER || (t->etype == tptr && t->type->etype == TINTER)) + return T; + s = t->sym; + if(s != S) + return t; + if(!isptr[t->etype]) + return T; + t = t->type; + if(t == T) + return T; + s = t->sym; + if(s != S) + return t; + return T; +} + +/* + * this is another ismethod() + * returns 1 if t=T and method wants *T + */ +int +needaddr(Type *t) +{ + Sym *s; + + if(t == T) + return 0; + if(t->etype == TINTER || (t->etype == tptr && t->type->etype == TINTER)) + return 0; + s = t->sym; + if(s != S && t->methptr == 2) + return 1; + return 0; +} + int iscomposite(Type *t) { diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index f8eb2e8a8a..1b7c1d31b5 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -1422,30 +1422,6 @@ walkselect(Node *sel) lineno = lno; } -Type* -methtype(Type *t) -{ - Sym *s; - - // this is ismethod() without diagnostics - if(t == T) - return T; - if(t->etype == TINTER || (t->etype == tptr && t->type->etype == TINTER)) - return T; - s = t->sym; - if(s != S && s->name[0] != '_') - return t; - if(!isptr[t->etype]) - return T; - t = t->type; - if(t == T) - return T; - s = t->sym; - if(s != S && s->name[0] != '_') - return t; - return T; -} - Type* lookdot1(Node *n, Type *f) { @@ -1495,6 +1471,10 @@ lookdot(Node *n, Type *t) } if(f2 != T) { + if(needaddr(n->left->type)) { + n->left = nod(OADDR, n->left, N); + n->left->type = ptrto(n->left->left->type); + } n->right = methodname(n->right, ismethod(n->left->type)); n->xoffset = f2->width; n->type = f2->type;