ref: 47d7e2b1035c7061eae7b46e174ebc7522729cb3
parent: a919b9614d3337fce9c8de0f235b163758875df4
author: Ori Bernstein <[email protected]>
date: Wed Jun 6 11:39:51 EDT 2012
Infer array sizes correctly. Ugh, embedding expressions in types feels hacky. Well, ya gotta do what ya gotta do.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -17,6 +17,8 @@
static void infernode(Node *n, Type *ret, int *sawret);
static void inferexpr(Node *n, Type *ret, int *sawret);
+static void typesub(Node *n);
+static Type *tf(Type *t);
static void setsuper(Stab *st, Stab *super)
{
@@ -33,9 +35,14 @@
int i, nn;
Node **n;
+ if (t->resolved)
+ return;
n = aggrmemb(t, &nn);
for (i = 0; i < nn; i++)
infernode(n[i], NULL, NULL);
+ for (i = 0; i < t->nsub; i++)
+ t->sub[i] = tf(t->sub[i]);
+ t->resolved = 1;
}
/* find the most accurate type mapping */
@@ -42,14 +49,14 @@
static Type *tf(Type *t)
{
Type *lu;
- assert(t != NULL);
+ assert(t != NULL);
+ lu = NULL;
while (1) {
if (!tytab[t->tid] && t->type == Tyname) {
if (!(lu = gettype(curstab(), t->name)))
- fatal(t->name->line, "Could not find type %s", t->name->name.parts[t->name->name.nparts - 1]);
+ fatal(t->name->line, "Could not find type %s", namestr(t->name));
tytab[t->tid] = lu;
- tyresolve(lu);
}
if (!tytab[t->tid])
@@ -56,6 +63,7 @@
break;
t = tytab[t->tid];
}
+ tyresolve(t);
return t;
}
@@ -392,7 +400,7 @@
{
Type *t;
- t = decltype(n);
+ t = tf(decltype(n));
settype(n, t);
if (n->decl.init) {
inferexpr(n->decl.init, NULL, NULL);
@@ -483,22 +491,30 @@
static Type *tyint;
int i;
char buf[1024];
+ Type *orig;
+ orig = t;
if (!tyint)
tyint = mkty(-1, Tyint);
t = tf(t);
if (t->type == Tyvar) {
- if (hascstr(t, cstrtab[Tcint]) && cstrcheck(t, tyint))
+ if (hascstr(t, cstrtab[Tcint]) && cstrcheck(t, tyint)) {
+ printf("int\n");
return tyint;
+ }
} else {
+ if (t->type == Tyarray)
+ typesub(t->asize);
for (i = 0; i < t->nsub; i++)
t->sub[i] = tyfin(ctx, t->sub[i]);
}
- if (t->type == Tyvar) {
+ if (t->type == Tyvar || t->type == Tyidxhack) {
dump(ctx, stdout);
fatal(t->line, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(ctx));
}
+
+ printf("fixing %s to %s\n", tystr(orig), tystr(t));
return t;
}
--- a/parse/node.c
+++ b/parse/node.c
@@ -265,6 +265,7 @@
case Tystruct: return t->sdecls; break;
case Tyunion: return t->udecls; break;
case Tyenum: return t->edecls; break;
+ case Tyarray: return &t->asize; break;
default: return NULL;
}
}
@@ -274,4 +275,3 @@
assert(name->type == Nname);
return name->name.parts[0];
}
-
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -97,6 +97,7 @@
Ty type;
int tid;
int line;
+ int resolved; /* Have we resolved the subtypes? Idempotent, but slow to repeat. */
Bitset *cstrs; /* the type constraints matched on this type */
size_t nsub; /* For compound types */
size_t nmemb; /* for aggregate types (struct, union, enum) */
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -240,20 +240,20 @@
case Tyname:
pickle(ty->name, fd);
break;
- case Typaram:
+ case Typaram:
wrstr(fd, ty->pname);
break;
- case Tystruct:
+ case Tystruct:
wrint(fd, ty->nmemb);
for (i = 0; i < ty->nmemb; i++)
pickle(ty->sdecls[i], fd);
break;
- case Tyunion:
+ case Tyunion:
wrint(fd, ty->nmemb);
for (i = 0; i < ty->nmemb; i++)
pickle(ty->udecls[i], fd);
break;
- case Tyenum:
+ case Tyenum:
wrint(fd, ty->nmemb);
for (i = 0; i < ty->nmemb; i++)
pickle(ty->edecls[i], fd);
@@ -262,8 +262,12 @@
wrtype(fd, ty->sub[0]);
pickle(ty->asize, fd);
break;
+ case Tyslice:
+ wrtype(fd, ty->sub[0]);
+ break;
case Tyvar:
- fprintf(stderr, "WARNING: Attempting to pickle Tyvar. This will not read back reliably.\n");
+ case Tyidxhack:
+ die("Attempting to pickle %s. This will not work.\n", tystr(ty));
break;
default:
for (i = 0; i < ty->nsub; i++)
@@ -315,6 +319,9 @@
case Tyarray:
ty->sub[0] = rdtype(fd);
ty->asize = unpickle(fd);
+ break;
+ case Tyslice:
+ ty->sub[0] = rdtype(fd);
break;
default:
for (i = 0; i < ty->nsub; i++)
--- a/parse/type.c
+++ b/parse/type.c
@@ -103,6 +103,7 @@
t = mkty(line, Tyarray);
t->nsub = 1;
+ t->nmemb = 1; /* the size is a "member" */
t->sub = xalloc(sizeof(Type*));
t->sub[0] = base;
t->asize = sz;