aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-12-22 20:22:18 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-12-22 20:29:26 -0700
commitcc937369fb8fed44e8e1b653f1f22805c84a3507 (patch)
tree70a851043cc1a3ca4c5ff93512f988388ed63e43 /src/type.zig
parente061d75cdf6a7994dd50f2d28c9f1ed3ed5ec205 (diff)
downloadzig-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.zig54
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),