aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2022-03-08 15:49:01 +0100
committerQuentin Carbonneaux <[email protected]>2022-03-08 15:57:06 +0100
commit9060981c10c21834596d5677a2c9ccc56809eb64 (patch)
tree2fe18c42b4c435a15612abdc4ce836d5860cdfa2
parent349794f3e4f11e4cc34a501ba935a2a305229738 (diff)
flag types defined as unions
The risc-v abi needs to know if a type is defined as a union or not. We cannot use nunion to obtain this information because the risc-v abi made the unfortunate decision of treating union { int i; } differently from int i; So, instead, I introduce a single bit flag 'isunion'.
-rw-r--r--all.h3
-rw-r--r--amd64/sysv.c2
-rw-r--r--arm64/abi.c2
-rw-r--r--parse.c10
-rw-r--r--rv64/abi.c2
5 files changed, 11 insertions, 8 deletions
diff --git a/all.h b/all.h
index a62b19b..f806c5b 100644
--- a/all.h
+++ b/all.h
@@ -357,7 +357,8 @@ struct Fn {
struct Typ {
char name[NString];
- int dark;
+ char isdark;
+ char isunion;
int align;
uint64_t size;
uint nunion;
diff --git a/amd64/sysv.c b/amd64/sysv.c
index 7287f41..e9f3d6b 100644
--- a/amd64/sysv.c
+++ b/amd64/sysv.c
@@ -77,7 +77,7 @@ typclass(AClass *a, Typ *t)
a->size = sz;
a->align = t->align;
- if (t->dark || sz > 16 || sz == 0) {
+ if (t->isdark || sz > 16 || sz == 0) {
/* large or unaligned structures are
* required to be passed in memory
*/
diff --git a/arm64/abi.c b/arm64/abi.c
index f127576..6ed393d 100644
--- a/arm64/abi.c
+++ b/arm64/abi.c
@@ -94,7 +94,7 @@ typclass(Class *c, Typ *t, int *gp, int *fp)
if (t->align > 4)
err("alignments larger than 16 are not supported");
- if (t->dark || sz > 16 || sz == 0) {
+ if (t->isdark || sz > 16 || sz == 0) {
/* large structs are replaced by a
* pointer to some caller-allocated
* memory */
diff --git a/parse.c b/parse.c
index c9638fd..70c291b 100644
--- a/parse.c
+++ b/parse.c
@@ -925,7 +925,8 @@ parsetyp()
*/
vgrow(&typ, ntyp+1);
ty = &typ[ntyp++];
- ty->dark = 0;
+ ty->isdark = 0;
+ ty->isunion = 0;
ty->align = -1;
ty->size = 0;
if (nextnl() != Ttyp || nextnl() != Teq)
@@ -944,7 +945,7 @@ parsetyp()
err("type body must start with {");
t = nextnl();
if (t == Tint) {
- ty->dark = 1;
+ ty->isdark = 1;
ty->size = tokval.num;
if (ty->align == -1)
err("dark types need alignment");
@@ -954,7 +955,8 @@ parsetyp()
}
n = 0;
ty->fields = vnew(1, sizeof ty->fields[0], Pheap);
- if (t == Tlbrace)
+ if (t == Tlbrace) {
+ ty->isunion = 1;
do {
if (t != Tlbrace)
err("invalid union member");
@@ -962,7 +964,7 @@ parsetyp()
parsefields(ty->fields[n++], ty, nextnl());
t = nextnl();
} while (t != Trbrace);
- else
+ } else
parsefields(ty->fields[n++], ty, t);
ty->nunion = n;
}
diff --git a/rv64/abi.c b/rv64/abi.c
index 05deabe..b49057b 100644
--- a/rv64/abi.c
+++ b/rv64/abi.c
@@ -105,7 +105,7 @@ typclass(Class *c, Typ *t, int *gp, int *fp)
if (t->align > 4)
err("alignments larger than 16 are not supported");
- if (t->dark || sz > 16 || sz == 0) {
+ if (t->isdark || sz > 16 || sz == 0) {
/* large structs are replaced by a
* pointer to some caller-allocated
* memory */