diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-12-22 20:22:18 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-12-22 20:29:26 -0700 |
| commit | cc937369fb8fed44e8e1b653f1f22805c84a3507 (patch) | |
| tree | 70a851043cc1a3ca4c5ff93512f988388ed63e43 /src/type.zig | |
| parent | e061d75cdf6a7994dd50f2d28c9f1ed3ed5ec205 (diff) | |
| download | zig-cc937369fb8fed44e8e1b653f1f22805c84a3507.tar.gz zig-cc937369fb8fed44e8e1b653f1f22805c84a3507.zip | |
stage2: `Type.hasCodeGenBits` asserts structs and unions have fields
Previously, this function would return an incorrect result for structs
and unions which did not have their fields resolved yet.
This required introducing more logic in Sema to resolve types before
doing certain things such as creating an anonmyous Decl and emitting
function call AIR.
As a result a couple more struct tests pass.
Oh, and I implemented the language change to make sizeOf for pointers
always return pointer size bytes even if the element type is 0 bits.
Diffstat (limited to 'src/type.zig')
| -rw-r--r-- | src/type.zig | 54 |
1 files changed, 11 insertions, 43 deletions
diff --git a/src/type.zig b/src/type.zig index fb16a4d0f1..6dd6af6cbc 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1518,8 +1518,6 @@ pub const Type = extern union { } } - /// For structs and unions, if the type does not have their fields resolved - /// this will return `false`. pub fn hasCodeGenBits(self: Type) bool { return switch (self.tag()) { .u1, @@ -1601,6 +1599,7 @@ pub const Type = extern union { if (struct_obj.known_has_bits) { return true; } + assert(struct_obj.haveFieldTypes()); for (struct_obj.fields.values()) |value| { if (value.ty.hasCodeGenBits()) return true; @@ -1623,6 +1622,7 @@ pub const Type = extern union { }, .@"union" => { const union_obj = self.castTag(.@"union").?.data; + assert(union_obj.haveFieldTypes()); for (union_obj.fields.values()) |value| { if (value.ty.hasCodeGenBits()) return true; @@ -1635,6 +1635,7 @@ pub const Type = extern union { if (union_obj.tag_ty.hasCodeGenBits()) { return true; } + assert(union_obj.haveFieldTypes()); for (union_obj.fields.values()) |value| { if (value.ty.hasCodeGenBits()) return true; @@ -2032,11 +2033,6 @@ pub const Type = extern union { .c_const_pointer, .c_mut_pointer, .pointer, - => { - if (!self.elemType().hasCodeGenBits()) return 0; - return @divExact(target.cpu.arch.ptrBitWidth(), 8); - }, - .manyptr_u8, .manyptr_const_u8, => return @divExact(target.cpu.arch.ptrBitWidth(), 8), @@ -2524,37 +2520,6 @@ pub const Type = extern union { return ty.ptrInfo().data.@"allowzero"; } - /// For pointer-like optionals, it returns the pointer type. For pointers, - /// the type is returned unmodified. - pub fn ptrOrOptionalPtrTy(ty: Type, buf: *Payload.ElemType) ?Type { - if (isPtrLikeOptional(ty)) return ty.optionalChild(buf); - switch (ty.tag()) { - .c_const_pointer, - .c_mut_pointer, - .single_const_pointer_to_comptime_int, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .manyptr_u8, - .manyptr_const_u8, - => return ty, - - .pointer => { - if (ty.ptrSize() == .Slice) { - return null; - } else { - return ty; - } - }, - - .inferred_alloc_const => unreachable, - .inferred_alloc_mut => unreachable, - - else => return null, - } - } - /// Returns true if the type is optional and would be lowered to a single pointer /// address value, using 0 for null. Note that this returns true for C pointers. pub fn isPtrLikeOptional(self: Type) bool { @@ -3393,11 +3358,14 @@ pub const Type = extern union { return null; } }, - .@"union" => { - return null; // TODO - }, - .union_tagged => { - return null; // TODO + .@"union", .union_tagged => { + const union_obj = ty.cast(Payload.Union).?.data; + const tag_val = union_obj.tag_ty.onePossibleValue() orelse return null; + const only_field = union_obj.fields.values()[0]; + const val_val = only_field.ty.onePossibleValue() orelse return null; + _ = tag_val; + _ = val_val; + return Value.initTag(.empty_struct_value); }, .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value), |
