diff options
Diffstat (limited to 'src/cmd/gc/subr.c')
-rw-r--r-- | src/cmd/gc/subr.c | 177 |
1 files changed, 122 insertions, 55 deletions
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 65b56dee6..3c4501096 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -228,11 +228,15 @@ linehist(char *file, int32 off, int relative) if(debug['i']) { if(file != nil) { if(off < 0) - print("pragma %s at line %L\n", file, lineno); + print("pragma %s", file); else - print("import %s at line %L\n", file, lineno); + if(off > 0) + print("line %s", file); + else + print("import %s", file); } else - print("end of import at line %L\n", lineno); + print("end of import"); + print(" at line %L\n", lexlineno); } if(off < 0 && file[0] != '/' && !relative) { @@ -267,7 +271,6 @@ setlineno(Node *n) case OTYPE: case OPACK: case OLITERAL: - case ONONAME: break; default: lineno = n->lineno; @@ -360,6 +363,8 @@ importdot(Pkg *opkg, Node *pack) for(s = hash[h]; s != S; s = s->link) { if(s->pkg != opkg) continue; + if(s->def == N) + continue; if(!exportname(s->name) || utfrune(s->name, 0xb7)) // 0xb7 = center dot continue; s1 = lookup(s->name); @@ -473,9 +478,12 @@ algtype(Type *t) int a; if(issimple[t->etype] || isptr[t->etype] || iscomplex[t->etype] || - t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP) - a = AMEM; // just bytes (int, ptr, etc) - else if(t->etype == TSTRING) + t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP) { + if(t->width == widthptr) + a = AMEMWORD; + else + a = AMEM; // just bytes (int, ptr, etc) + } else if(t->etype == TSTRING) a = ASTRING; // string else if(isnilinter(t)) a = ANILINTER; // nil interface @@ -584,6 +592,21 @@ nodintconst(int64 v) return c; } +Node* +nodfltconst(Mpflt* v) +{ + Node *c; + + c = nod(OLITERAL, N, N); + c->addable = 1; + c->val.u.fval = mal(sizeof(*c->val.u.fval)); + mpmovefltflt(c->val.u.fval, v); + c->val.ctype = CTFLT; + c->type = types[TIDEAL]; + ullmancalc(c); + return c; +} + void nodconst(Node *n, Type *t, int64 v) { @@ -804,6 +827,7 @@ goopnames[] = [OANDAND] = "&&", [OANDNOT] = "&^", [OAND] = "&", + [OAPPEND] = "append", [OAS] = "=", [OAS2] = "=", [OBREAK] = "break", @@ -894,12 +918,21 @@ Lconv(Fmt *fp) if(lno < h->line) break; if(h->name) { - if(n < HISTSZ) { /* beginning of file */ - a[n].incl = h; - a[n].idel = h->line; - a[n].line = 0; + if(h->offset > 0) { + // #line directive + if(n > 0 && n < HISTSZ) { + a[n-1].line = h; + a[n-1].ldel = h->line - h->offset + 1; + } + } else { + // beginning of file + if(n < HISTSZ) { + a[n].incl = h; + a[n].idel = h->line; + a[n].line = 0; + } + n++; } - n++; continue; } n--; @@ -919,14 +952,16 @@ Lconv(Fmt *fp) break; fmtprint(fp, " "); } + if(debug['L']) + fmtprint(fp, "%s/", pathname); if(a[i].line) - fmtprint(fp, "%s:%ld[%s:%ld]", + fmtprint(fp, "%s:%d[%s:%d]", a[i].line->name, lno-a[i].ldel+1, a[i].incl->name, lno-a[i].idel+1); else - fmtprint(fp, "%s:%ld", + fmtprint(fp, "%s:%d", a[i].incl->name, lno-a[i].idel+1); - lno = a[i].incl->line - 1; /* now print out start of this file */ + lno = a[i].incl->line - 1; // now print out start of this file } if(n == 0) fmtprint(fp, "<epoch>"); @@ -1003,10 +1038,10 @@ Jconv(Fmt *fp) fmtprint(fp, " a(%d)", n->addable); if(n->vargen != 0) - fmtprint(fp, " g(%ld)", n->vargen); + fmtprint(fp, " g(%d)", n->vargen); if(n->lineno != 0) - fmtprint(fp, " l(%ld)", n->lineno); + fmtprint(fp, " l(%d)", n->lineno); if(n->xoffset != 0) fmtprint(fp, " x(%lld)", n->xoffset); @@ -1029,6 +1064,9 @@ Jconv(Fmt *fp) if(n->isddd != 0) fmtprint(fp, " isddd(%d)", n->isddd); + if(n->implicit != 0) + fmtprint(fp, " implicit(%d)", n->implicit); + return 0; } @@ -1146,7 +1184,7 @@ Tpretty(Fmt *fp, Type *t) case Csend: return fmtprint(fp, "chan<- %T", t->type); } - if(t->type != T && t->type->etype == TCHAN && t->type->chan == Crecv) + if(t->type != T && t->type->etype == TCHAN && t->type->sym == S && t->type->chan == Crecv) return fmtprint(fp, "chan (%T)", t->type); return fmtprint(fp, "chan %T", t->type); @@ -1256,7 +1294,7 @@ Tpretty(Fmt *fp, Type *t) fmtprint(fp, "...%T", t->type->type); else fmtprint(fp, "%T", t->type); - if(t->note) { + if(t->note) { fmtprint(fp, " "); if(exporting) fmtprint(fp, ":"); @@ -1360,7 +1398,7 @@ Tconv(Fmt *fp) case TARRAY: if(t->bound >= 0) - fmtprint(fp, "[%ld]%T", t->bound, t->type); + fmtprint(fp, "[%d]%T", t->bound, t->type); else fmtprint(fp, "[]%T", t->type); break; @@ -1414,7 +1452,7 @@ Nconv(Fmt *fp) fmtprint(fp, "%O%J", n->op, n); break; } - fmtprint(fp, "%O-%S G%ld%J", n->op, + fmtprint(fp, "%O-%S G%d%J", n->op, n->sym, n->vargen, n); goto ptyp; @@ -1460,7 +1498,7 @@ Nconv(Fmt *fp) break; } if(n->sym != S) - fmtprint(fp, " %S G%ld", n->sym, n->vargen); + fmtprint(fp, " %S G%d", n->sym, n->vargen); ptyp: if(n->type != T) @@ -1909,13 +1947,6 @@ assignop(Type *src, Type *dst, char **why) // 7. Any typed value can be assigned to the blank identifier. if(dst->etype == TBLANK) return OCONVNOP; - - // 8. Array to slice. - // TODO(rsc): Not for long. - if(!src->sym || !dst->sym) - if(isptr[src->etype] && isfixedarray(src->type) && isslice(dst)) - if(eqtype(src->type->type, dst->type)) - return OCONVSLICE; return 0; } @@ -2037,6 +2068,7 @@ assignconv(Node *n, Type *t, char *context) r = nod(op, n, N); r->type = t; r->typecheck = 1; + r->implicit = 1; return r; } @@ -2292,7 +2324,8 @@ ptrto(Type *t) fatal("ptrto: nil"); t1 = typ(tptr); t1->type = t; - t1->width = types[tptr]->width; + t1->width = widthptr; + t1->align = widthptr; return t1; } @@ -2320,7 +2353,7 @@ frame(int context) case ONAME: if(flag) print("--- %s frame ---\n", p); - print("%O %S G%ld %T\n", n->op, n->sym, n->vargen, n->type); + print("%O %S G%d %T\n", n->op, n->sym, n->vargen, n->type); flag = 0; break; @@ -2584,20 +2617,8 @@ brrev(int a) return a; } -Node* -staticname(Type *t) -{ - Node *n; - - snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen); - statuniqgen++; - n = newname(lookup(namebuf)); - addvar(n, t, PEXTERN); - return n; -} - /* - * return side effect-free appending side effects to init. + * return side effect-free n, appending side effects to init. * result is assignable if n is. */ Node* @@ -2654,6 +2675,24 @@ safeexpr(Node *n, NodeList **init) // make a copy; must not be used as an lvalue if(islvalue(n)) fatal("missing lvalue case in safeexpr: %N", n); + return cheapexpr(n, init); +} + +/* + * return side-effect free and cheap n, appending side effects to init. + * result may not be assignable. + */ +Node* +cheapexpr(Node *n, NodeList **init) +{ + Node *a, *l; + + switch(n->op) { + case ONAME: + case OLITERAL: + return n; + } + l = nod(OXXX, N, N); tempname(l, n->type); a = nod(OAS, l, n); @@ -2939,6 +2978,11 @@ expandmeth(Sym *s, Type *t) if(t == T || t->xmethod != nil) return; + // mark top-level method symbols + // so that expand1 doesn't consider them. + for(f=t->method; f != nil; f=f->down) + f->sym->flags |= SymUniq; + // generate all reachable methods slist = nil; expand1(t, nelem(dotlist)-1, 0); @@ -2958,6 +3002,9 @@ expandmeth(Sym *s, Type *t) } } + for(f=t->method; f != nil; f=f->down) + f->sym->flags &= ~SymUniq; + t->xmethod = t->method; for(sl=slist; sl!=nil; sl=sl->link) { if(sl->good) { @@ -2969,7 +3016,6 @@ expandmeth(Sym *s, Type *t) f->embedded = 2; f->down = t->xmethod; t->xmethod = f; - } } } @@ -3031,15 +3077,19 @@ structargs(Type **tl, int mustname) * newnam - the eventual mangled name of this function */ void -genwrapper(Type *rcvr, Type *method, Sym *newnam) +genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) { - Node *this, *fn, *call, *n, *t; + Node *this, *fn, *call, *n, *t, *pad; NodeList *l, *args, *in, *out; + Type *tpad; + int isddd; if(debug['r']) print("genwrapper rcvrtype=%T method=%T newnam=%S\n", rcvr, method, newnam); + lineno = 1; // less confusing than end of input + dclcontext = PEXTERN; markdcl(); @@ -3050,20 +3100,37 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam) fn = nod(ODCLFUNC, N, N); fn->nname = newname(newnam); - t = nod(OTFUNC, this, N); - t->list = in; + t = nod(OTFUNC, N, N); + l = list1(this); + if(iface && rcvr->width < types[tptr]->width) { + // Building method for interface table and receiver + // is smaller than the single pointer-sized word + // that the interface call will pass in. + // Add a dummy padding argument after the + // receiver to make up the difference. + tpad = typ(TARRAY); + tpad->type = types[TUINT8]; + tpad->bound = types[tptr]->width - rcvr->width; + pad = nod(ODCLFIELD, newname(lookup(".pad")), typenod(tpad)); + l = list(l, pad); + } + t->list = concat(l, in); t->rlist = out; fn->nname->ntype = t; funchdr(fn); // arg list args = nil; - for(l=in; l; l=l->next) + isddd = 0; + for(l=in; l; l=l->next) { args = list(args, l->n->left); + isddd = l->n->left->isddd; + } // generate call call = nod(OCALL, adddot(nod(OXDOT, this->left, newname(method->sym))), N); call->list = args; + call->isddd = isddd; fn->nbody = list1(call); if(method->type->outtuple > 0) { n = nod(ORETURN, N, N); @@ -3563,10 +3630,11 @@ umagic(Magic *m) Sym* ngotype(Node *n) { - if(n->sym != S && strncmp(n->sym->name, "autotmp_", 8) != 0) - if(n->type->etype != TFUNC || n->type->thistuple == 0) - if(n->type->etype != TSTRUCT || n->type->funarg == 0) - return typename(n->type)->left->sym; + 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; + return S; } @@ -3640,4 +3708,3 @@ strlit(char *s) t->len = strlen(s); return t; } - |