diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-12-01 00:34:29 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-12-01 00:34:29 -0500 |
| commit | 264c86853b714482d006baa38482a6f7d55e8d94 (patch) | |
| tree | 2e402053b226aeae2dbbf732edaa761cdeb8828b | |
| parent | b62e2fd8703129fcf0dc80675800f005e84ee724 (diff) | |
| download | zig-264c86853b714482d006baa38482a6f7d55e8d94.tar.gz zig-264c86853b714482d006baa38482a6f7d55e8d94.zip | |
packed structs can have enums with explicit tag types
See #305
| -rw-r--r-- | src/analyze.cpp | 4 | ||||
| -rw-r--r-- | src/codegen.cpp | 9 | ||||
| -rw-r--r-- | test/cases/enum.zig | 70 |
3 files changed, 81 insertions, 2 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 33d6ccdc39..235aeea682 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1536,7 +1536,6 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { case TypeTableEntryIdNullLit: case TypeTableEntryIdErrorUnion: case TypeTableEntryIdPureError: - case TypeTableEntryIdEnum: case TypeTableEntryIdEnumTag: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: @@ -1560,6 +1559,9 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { TypeTableEntry *child_type = type_entry->data.maybe.child_type; return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; } + case TypeTableEntryIdEnum: + return type_entry->data.enumeration.gen_field_count == 0 && + type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr; } zig_unreachable(); } diff --git a/src/codegen.cpp b/src/codegen.cpp index da94dd4bcd..a5f8b85e22 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3762,7 +3762,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con case TypeTableEntryIdNullLit: case TypeTableEntryIdErrorUnion: case TypeTableEntryIdPureError: - case TypeTableEntryIdEnum: case TypeTableEntryIdEnumTag: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: @@ -3773,6 +3772,13 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con zig_unreachable(); case TypeTableEntryIdBool: return LLVMConstInt(big_int_type_ref, const_val->data.x_bool ? 1 : 0, false); + case TypeTableEntryIdEnum: + { + assert(type_entry->data.enumeration.gen_field_count == 0); + assert(type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr); + LLVMValueRef int_val = gen_const_val(g, const_val); + return LLVMConstZExt(int_val, big_int_type_ref); + } case TypeTableEntryIdInt: { LLVMValueRef int_val = gen_const_val(g, const_val); @@ -3814,6 +3820,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con } return val; } + } zig_unreachable(); } diff --git a/test/cases/enum.zig b/test/cases/enum.zig index a56ed398b8..1b2ff10a9b 100644 --- a/test/cases/enum.zig +++ b/test/cases/enum.zig @@ -214,3 +214,73 @@ test "set enum tag type" { comptime assert(@EnumTagType(Small2) == u2); } } + + +const A = enum (u3) { + One, + Two, + Three, + Four, + One2, + Two2, + Three2, + Four2, +}; + +const B = enum (u3) { + One3, + Two3, + Three3, + Four3, + One23, + Two23, + Three23, + Four23, +}; + +const C = enum (u2) { + One4, + Two4, + Three4, + Four4, +}; + +const BitFieldOfEnums = packed struct { + a: A, + b: B, + c: C, +}; + +const bit_field_1 = BitFieldOfEnums { + .a = A.Two, + .b = B.Three3, + .c = C.Four4, +}; + +test "bit field access with enum fields" { + var data = bit_field_1; + assert(getA(&data) == A.Two); + assert(getB(&data) == B.Three3); + assert(getC(&data) == C.Four4); + comptime assert(@sizeOf(BitFieldOfEnums) == 1); + + data.b = B.Four3; + assert(data.b == B.Four3); + + data.a = A.Three; + assert(data.a == A.Three); + assert(data.b == B.Four3); +} + +fn getA(data: &const BitFieldOfEnums) -> A { + return data.a; +} + +fn getB(data: &const BitFieldOfEnums) -> B { + return data.b; +} + +fn getC(data: &const BitFieldOfEnums) -> C { + return data.c; +} + |
