diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-05 23:05:14 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-05 23:05:14 -0700 |
| commit | e16ddad49f1b3e4ce10ce8fb653e48f24a9d4837 (patch) | |
| tree | 131a0873355fecce3c1abac1d0f42b8cab27d515 /src/codegen/llvm.zig | |
| parent | cb616cb7972bb2f38ea4527c7ec0ae3cc0d64c7c (diff) | |
| download | zig-e16ddad49f1b3e4ce10ce8fb653e48f24a9d4837.tar.gz zig-e16ddad49f1b3e4ce10ce8fb653e48f24a9d4837.zip | |
stage2: enum fixes
* Sema: fix a missing copy on enum tag values
* LLVM backend: fix lowering of enum constant values for enums with
specified tag values.
* Value: fix enumToInt for `enum_numbered` cases.
The float widening behavior tests which rely on compiler-rt symbols are
now passing.
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 00df4346d2..ceaca07a49 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -889,9 +889,9 @@ pub const DeclGen = struct { .Int => { var bigint_space: Value.BigIntSpace = undefined; const bigint = tv.val.toBigInt(&bigint_space); - - const llvm_type = try self.llvmType(tv.ty); - if (bigint.eqZero()) return llvm_type.constNull(); + const target = self.module.getTarget(); + const int_info = tv.ty.intInfo(target); + const llvm_type = self.context.intType(int_info.bits); const unsigned_val = if (bigint.limbs.len == 1) llvm_type.constInt(bigint.limbs[0], .False) @@ -903,15 +903,24 @@ pub const DeclGen = struct { return unsigned_val; }, .Enum => { - const llvm_type = try self.llvmType(tv.ty); - const uint: u64 = uint: { - if (tv.val.castTag(.enum_field_index)) |payload| { - break :uint payload.data; - } - break :uint tv.val.toUnsignedInt(); - }; - const llvm_int = llvm_type.constInt(uint, .False); - return llvm_int; + var int_buffer: Value.Payload.U64 = undefined; + const int_val = tv.enumToInt(&int_buffer); + + var bigint_space: Value.BigIntSpace = undefined; + const bigint = int_val.toBigInt(&bigint_space); + + const target = self.module.getTarget(); + const int_info = tv.ty.intInfo(target); + const llvm_type = self.context.intType(int_info.bits); + + const unsigned_val = if (bigint.limbs.len == 1) + llvm_type.constInt(bigint.limbs[0], .False) + else + llvm_type.constIntOfArbitraryPrecision(@intCast(c_uint, bigint.limbs.len), bigint.limbs.ptr); + if (!bigint.positive) { + return llvm.constNeg(unsigned_val); + } + return unsigned_val; }, .Float => { const llvm_ty = try self.llvmType(tv.ty); |
