summaryrefslogtreecommitdiff
path: root/src/cmd/gc/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/subr.c')
-rw-r--r--src/cmd/gc/subr.c184
1 files changed, 170 insertions, 14 deletions
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 37375342c..8d2491535 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -36,7 +36,7 @@ warn(char *fmt, ...)
{
va_list arg;
- print("%L warning: ");
+ print("%L: ");
va_start(arg, fmt);
vfprint(1, fmt, arg);
va_end(arg);
@@ -50,7 +50,7 @@ fatal(char *fmt, ...)
{
va_list arg;
- print("%L fatal error: ");
+ print("%L: fatal error: ");
va_start(arg, fmt);
vfprint(1, fmt, arg);
va_end(arg);
@@ -344,7 +344,7 @@ aindex(Node *b, Type *t)
if(t->etype == TDARRAY)
yyerror("dynamic array type cannot be a dynamic array");
- walktype(b, 0);
+ walktype(b, Erv);
switch(whatis(b)) {
default:
yyerror("array bound must be a constant integer expression");
@@ -754,6 +754,7 @@ etnames[] =
[TFIELD] = "FIELD",
[TSTRING] = "STRING",
[TCHAN] = "CHAN",
+ [TANY] = "ANY",
};
int
@@ -884,6 +885,7 @@ Tconv(Fmt *fp)
strcpy(buf, "");
if(t->sym != S) {
+ if(t->sym->name[0] != '_')
snprint(buf, sizeof(buf), "<%S>", t->sym);
}
if(t->trecur > 5) {
@@ -908,13 +910,13 @@ Tconv(Fmt *fp)
case TFUNC:
if(fp->flags & FmtLong)
- snprint(buf1, sizeof(buf1), "%d%d%d(%lT,%lT,%lT)",
- t->thistuple, t->outtuple, t->intuple,
- t->type, t->type->down, t->type->down->down);
+ snprint(buf1, sizeof(buf1), "%d%d%d(%lT,%lT)%lT",
+ t->thistuple, t->intuple, t->outtuple,
+ t->type, t->type->down->down, t->type->down);
else
- snprint(buf1, sizeof(buf1), "%d%d%d(%T,%T,%T)",
- t->thistuple, t->outtuple, t->intuple,
- t->type, t->type->down, t->type->down->down);
+ snprint(buf1, sizeof(buf1), "%d%d%d(%T,%T)%T",
+ t->thistuple, t->intuple, t->outtuple,
+ t->type, t->type->down->down, t->type->down);
strncat(buf, buf1, sizeof(buf));
break;
@@ -1205,6 +1207,141 @@ eqtype(Type *t1, Type *t2, int d)
return eqtype(t1->type, t2->type, d+1);
}
+static int
+subtype(Type **stp, Type *t)
+{
+ Type *st;
+
+loop:
+ st = *stp;
+ if(st == T)
+ return 0;
+ switch(st->etype) {
+ default:
+ return 0;
+
+ case TPTR32:
+ case TPTR64:
+ stp = &st->type;
+ goto loop;
+
+ case TANY:
+ *stp = t;
+ break;
+
+ case TMAP:
+ if(subtype(&st->down, t))
+ break;
+ stp = &st->type;
+ goto loop;
+
+ case TFUNC:
+ for(;;) {
+ if(subtype(&st->type, t))
+ break;
+ if(subtype(&st->type->down->down, t))
+ break;
+ if(subtype(&st->type->down, t))
+ break;
+ return 0;
+ }
+ break;
+
+ case TSTRUCT:
+ for(st=st->type; st!=T; st=st->down)
+ if(subtype(&st->type, t))
+ return 1;
+ return 0;
+ }
+ return 1;
+}
+
+void
+argtype(Node *on, Type *t)
+{
+ if(!subtype(&on->type, t))
+ fatal("argtype: failed %N %T\n", on, t);
+}
+
+Type*
+shallow(Type *t)
+{
+ Type *nt;
+
+ if(t == T)
+ return T;
+ nt = typ(0);
+ *nt = *t;
+ return nt;
+}
+
+Type*
+deep(Type *t)
+{
+ Type *nt, *xt;
+
+ if(t == T)
+ return T;
+
+ switch(t->etype) {
+ default:
+ nt = t; // share from here down
+ break;
+
+ case TPTR32:
+ case TPTR64:
+ nt = shallow(t);
+ nt->type = deep(t->type);
+ break;
+
+ case TMAP:
+ nt = shallow(t);
+ nt->down = deep(t->down);
+ nt->type = deep(t->type);
+ break;
+
+ case TFUNC:
+ nt = shallow(t);
+ nt->type = deep(t->type);
+ nt->type->down = deep(t->type->down);
+ nt->type->down->down = deep(t->type->down->down);
+ break;
+
+ case TSTRUCT:
+ nt = shallow(t);
+ nt->type = shallow(t->type);
+ xt = nt->type;
+
+ for(t=t->type; t!=T; t=t->down) {
+ xt->type = deep(t->type);
+ xt->down = shallow(t->down);
+ xt = xt->down;
+ }
+ break;
+ }
+ return nt;
+}
+
+Node*
+syslook(char *name, int copy)
+{
+ Sym *s;
+ Node *n;
+
+ s = pkglookup(name, "sys");
+ if(s == S || s->oname == N)
+ fatal("looksys: cant find sys.%s", name);
+
+ if(!copy)
+ return s->oname;
+
+ n = nod(0, N, N);
+ *n = *s->oname;
+ n->type = deep(s->oname->type);
+
+ return n;
+}
+
/*
* are the arg names of two
* functions the same. we know
@@ -1386,13 +1523,27 @@ out:
void
badtype(int o, Type *tl, Type *tr)
{
- yyerror("illegal types for operand");
+
+loop:
+ switch(o) {
+ case OCALL:
+ if(tl == T || tr == T)
+ break;
+ if(isptr[tl->etype] && isptr[tr->etype]) {
+ tl = tl->type;
+ tr = tr->type;
+ goto loop;
+ }
+ if(tl->etype != TFUNC || tr->etype != TFUNC)
+ break;
+// if(eqtype(t1, t2, 0))
+ }
+
+ yyerror("illegal types for operand: %O", o);
if(tl != T)
- print(" (%T)", tl);
- print(" %O ", o);
+ print(" (%lT)\n", tl);
if(tr != T)
- print("(%T)", tr);
- print("\n");
+ print(" (%lT)\n", tr);
}
/*
@@ -1605,6 +1756,11 @@ listnext(Iter *s)
n = s->n;
r = n->right;
+ if(r == N) {
+ s->an = &s->n;
+ s->n = N;
+ return N;
+ }
if(r->op == OLIST) {
s->n = r;
s->an = &r->left;