ref: 01243d18cc0d8795a9887bc3565d5f48ce3c9430
parent: a537b8fe4a69dea9e3150b01785b18c5d4d3b374
author: Ori Bernstein <[email protected]>
date: Thu Dec 18 09:52:43 EST 2014
Fix up type equality/hashing. Now more things that should be equal will compare or hash as equal.
--- a/parse/type.c
+++ b/parse/type.c
@@ -633,10 +633,13 @@
ulong hash;
t = (Type *)ty;
- if (t->type == Typaram)
- hash = strhash(t->pname);
- else
- hash = inthash(t->tid);
+ switch (t->type) {
+ case Typaram: hash = strhash(t->pname); break;
+ case Tyvar: hash = inthash(t->tid); break;
+ case Tyunion: hash = inthash(t->tid); break;
+ case Tystruct: hash = inthash(t->tid); break;
+ default: hash = inthash(t->type); break;
+ }
for (i = 0; i < t->narg; i++)
hash ^= tyhash(t->arg[i]);
@@ -643,6 +646,22 @@
return hash;
}
+static int valeq(Node *a, Node *b)
+{
+ if (a == b)
+ return 1;
+
+ /* unwrap to Nlit */
+ if (exprop(a) == Olit)
+ a = a->expr.args[0];
+ if (exprop(b) == Olit)
+ b = b->expr.args[0];
+
+ if (a->type != Nlit || b->type != Nlit)
+ return 0;
+ return liteq(a, b);
+}
+
int tyeq(void *t1, void *t2)
{
Type *a, *b;
@@ -652,6 +671,8 @@
b = (Type *)t2;
if (a == b)
return 1;
+ if (!a || !b)
+ return 0;
if (a->type != b->type)
return 0;
if (a->tid == b->tid)
@@ -666,11 +687,20 @@
case Typaram:
return streq(a->pname, b->pname);
break;
+ case Tyvar:
+ if (a->tid != b->tid)
+ return 0;
+ break;
case Tyunion:
for (i = 0; i < a->nmemb; i++)
if (!tyeq(a->udecls[i]->etype, b->udecls[i]->etype))
return 0;
break;
+ case Tystruct:
+ for (i = 0; i < a->nmemb; i++)
+ if (strcmp(declname(a->sdecls[i]), declname(b->sdecls[i])) != 0)
+ return 0;
+ break;
case Tyname:
if (!nameeq(a->name, b->name))
return 0;
@@ -681,12 +711,16 @@
if (!tyeq(a->sub[i], b->sub[i]))
return 0;
break;
+ case Tyarray:
+ if (!valeq(a->asize, b->asize))
+ return 0;
+ break;
default:
- for (i = 0; i < a->nsub; i++)
- if (!tyeq(a->sub[i], b->sub[i]))
- return 0;
break;
}
+ for (i = 0; i < a->nsub; i++)
+ if (!tyeq(a->sub[i], b->sub[i]))
+ return 0;
return 1;
}