aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2019-02-21 12:22:22 -0800
committerMichael Forney <mforney@mforney.org>2019-02-21 12:22:22 -0800
commit9c80c96e84c398165df1cd304c32229acb8328dc (patch)
tree9b2a3d20100b48048c88e93a18e719d10b6e9183
parent1abf2329fe59afa7490a8c5e5a90ef74fbaab8cd (diff)
downloadcproc-9c80c96e84c398165df1cd304c32229acb8328dc.tar.xz
Emit complete union type definitions instead of just using the first member
-rw-r--r--README.md1
-rw-r--r--qbe.c13
-rw-r--r--tests/union-passing.c2
-rw-r--r--tests/union-passing.qbe2
4 files changed, 7 insertions, 11 deletions
diff --git a/README.md b/README.md
index 40d9fbb..0d6a353 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,6 @@ Still TODO:
- Come up with a name so it can be installed alongside the system `cc`.
- The preprocessor (currently we are just using the system `cpp`).
- Bit-fields.
-- Passing structs with embedded unions by value.
- Variable-length arrays.
- `volatile`-qualified types (requires support from QBE).
- `_Thread_local` storage-class specifier (requires support from QBE).
diff --git a/qbe.c b/qbe.c
index 75be4c5..7cc0719 100644
--- a/qbe.c
+++ b/qbe.c
@@ -979,12 +979,6 @@ emitrepr(struct representation *r, bool abi, bool ext)
}
/* XXX: need to consider _Alignas on struct members */
-/* XXX: this might not be right for something like
-union {
- struct { long long x; double y; };
- struct { double z; long long w; };
-};
-*/
static void
emittype(struct type *t)
{
@@ -1008,14 +1002,17 @@ emittype(struct type *t)
emitname(&t->repr->abi);
fputs(" = { ", stdout);
for (m = t->structunion.members; m; m = m->next) {
+ if (t->kind == TYPEUNION)
+ fputs("{ ", stdout);
for (i = 1, sub = m->type; sub->kind == TYPEARRAY; sub = sub->base)
i *= sub->array.length;
emitrepr(sub->repr, true, true);
if (i > 1)
printf(" %" PRIu64, i);
- fputs(", ", stdout);
if (t->kind == TYPEUNION)
- break;
+ fputs(" } ", stdout);
+ else
+ fputs(", ", stdout);
}
puts("}");
}
diff --git a/tests/union-passing.c b/tests/union-passing.c
index 14025c0..ddf35f2 100644
--- a/tests/union-passing.c
+++ b/tests/union-passing.c
@@ -1,2 +1,2 @@
-void f(union {int x;} u) {
+void f(union {int x; float y;} u) {
}
diff --git a/tests/union-passing.qbe b/tests/union-passing.qbe
index 96e8523..2edd8db 100644
--- a/tests/union-passing.qbe
+++ b/tests/union-passing.qbe
@@ -1,4 +1,4 @@
-type :.1 = { w, }
+type :.1 = { { w } { s } }
export
function $f(:.1 %.1) {
@start.1