shithub: mc

Download patch

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;