#define MY_ASSERT(...) do { } while (0) #define MY_ATTRS __attribute((noinline)) #include #include #include #include #include struct I; struct H { enum class Tag : uint8_t { H_Foo, H_Bar, H_Baz, }; struct H_Foo_Body { int16_t _0; }; struct H_Bar_Body { uint8_t x; int16_t y; }; Tag tag; union { H_Foo_Body foo; H_Bar_Body bar; }; static H H_Foo(const int16_t &_0) { H result; ::new (&result.foo._0) (int16_t)(_0); result.tag = Tag::H_Foo; return result; } bool IsH_Foo() const { return tag == Tag::H_Foo; } const int16_t& AsH_Foo() const { MY_ASSERT(IsH_Foo()); return foo._0; } MY_ATTRS int16_t& AsH_Foo() { MY_ASSERT(IsH_Foo()); return foo._0; } static H H_Bar(const uint8_t &x, const int16_t &y) { H result; ::new (&result.bar.x) (uint8_t)(x); ::new (&result.bar.y) (int16_t)(y); result.tag = Tag::H_Bar; return result; } bool IsH_Bar() const { return tag == Tag::H_Bar; } MY_ATTRS const H_Bar_Body& AsH_Bar() const { MY_ASSERT(IsH_Bar()); return bar; } H_Bar_Body& AsH_Bar() { MY_ASSERT(IsH_Bar()); return bar; } static H H_Baz() { H result; result.tag = Tag::H_Baz; return result; } MY_ATTRS bool IsH_Baz() const { return tag == Tag::H_Baz; } }; struct J { enum class Tag : uint8_t { J_Foo, J_Bar, J_Baz, }; struct J_Foo_Body { int16_t _0; }; struct J_Bar_Body { uint8_t x; int16_t y; }; Tag tag; union { J_Foo_Body foo; J_Bar_Body bar; }; static J J_Foo(const int16_t &_0) { J result; ::new (&result.foo._0) (int16_t)(_0); result.tag = Tag::J_Foo; return result; } bool IsJ_Foo() const { return tag == Tag::J_Foo; } const int16_t& AsJ_Foo() const { MY_ASSERT(IsJ_Foo()); return foo._0; } int16_t& AsJ_Foo() { MY_ASSERT(IsJ_Foo()); return foo._0; } static J J_Bar(const uint8_t &x, const int16_t &y) { J result; ::new (&result.bar.x) (uint8_t)(x); ::new (&result.bar.y) (int16_t)(y); result.tag = Tag::J_Bar; return result; } bool IsJ_Bar() const { return tag == Tag::J_Bar; } const J_Bar_Body& AsJ_Bar() const { MY_ASSERT(IsJ_Bar()); return bar; } J_Bar_Body& AsJ_Bar() { MY_ASSERT(IsJ_Bar()); return bar; } static J J_Baz() { J result; result.tag = Tag::J_Baz; return result; } bool IsJ_Baz() const { return tag == Tag::J_Baz; } }; union K { enum class Tag : uint8_t { K_Foo, K_Bar, K_Baz, }; struct K_Foo_Body { Tag tag; int16_t _0; }; struct K_Bar_Body { Tag tag; uint8_t x; int16_t y; }; struct { Tag tag; }; K_Foo_Body foo; K_Bar_Body bar; static K K_Foo(const int16_t &_0) { K result; ::new (&result.foo._0) (int16_t)(_0); result.tag = Tag::K_Foo; return result; } bool IsK_Foo() const { return tag == Tag::K_Foo; } const int16_t& AsK_Foo() const { MY_ASSERT(IsK_Foo()); return foo._0; } int16_t& AsK_Foo() { MY_ASSERT(IsK_Foo()); return foo._0; } static K K_Bar(const uint8_t &x, const int16_t &y) { K result; ::new (&result.bar.x) (uint8_t)(x); ::new (&result.bar.y) (int16_t)(y); result.tag = Tag::K_Bar; return result; } bool IsK_Bar() const { return tag == Tag::K_Bar; } const K_Bar_Body& AsK_Bar() const { MY_ASSERT(IsK_Bar()); return bar; } K_Bar_Body& AsK_Bar() { MY_ASSERT(IsK_Bar()); return bar; } static K K_Baz() { K result; result.tag = Tag::K_Baz; return result; } bool IsK_Baz() const { return tag == Tag::K_Baz; } }; extern "C" { void foo(H h, I i, J j, K k); } // extern "C"