aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-02-25 21:04:23 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-02-25 21:04:23 -0700
commit0b58b617998b79a765b54f88fbe90ca2798b3d3e (patch)
treeca6cc4b6bcc2b93166d196049ee49416afe781ad /src/type.zig
parentdc325669e360f7a9dfa24f85a62fa386529dade6 (diff)
parentfd208d9d5913a0929e444deb97b91092c427bb14 (diff)
downloadzig-0b58b617998b79a765b54f88fbe90ca2798b3d3e.tar.gz
zig-0b58b617998b79a765b54f88fbe90ca2798b3d3e.zip
Merge remote-tracking branch 'origin/master' into llvm12
Conflicts: * src/clang.zig * src/llvm.zig - this file got moved to src/llvm/bindings.zig in master branch so I had to put the new LLVM arch/os enum tags into it. * lib/std/target.zig, src/stage1/target.cpp - haiku had an inconsistency with its default target ABI, gnu vs eabi. In this commit we make it gnu in both places to match the latest changes by @hoanga. * src/translate_c.zig
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig1145
1 files changed, 779 insertions, 366 deletions
diff --git a/src/type.zig b/src/type.zig
index 58d89a8140..30605ce67b 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -28,6 +28,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -49,7 +51,7 @@ pub const Type = extern union {
.c_longdouble,
=> return .Float,
- .c_void => return .Opaque,
+ .c_void, .@"opaque" => return .Opaque,
.bool => return .Bool,
.void => return .Void,
.type => return .Type,
@@ -78,6 +80,8 @@ pub const Type = extern union {
.const_slice,
.mut_slice,
.pointer,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
=> return .Pointer,
.optional,
@@ -90,7 +94,9 @@ pub const Type = extern union {
.anyframe_T, .@"anyframe" => return .AnyFrame,
- .empty_struct => return .Struct,
+ .@"struct", .empty_struct => return .Struct,
+ .@"enum" => return .Enum,
+ .@"union" => return .Union,
}
}
@@ -106,24 +112,45 @@ pub const Type = extern union {
pub fn tag(self: Type) Tag {
if (self.tag_if_small_enough < Tag.no_payload_count) {
- return @intToEnum(Tag, @intCast(@TagType(Tag), self.tag_if_small_enough));
+ return @intToEnum(Tag, @intCast(std.meta.Tag(Tag), self.tag_if_small_enough));
} else {
return self.ptr_otherwise.tag;
}
}
+ /// Prefer `castTag` to this.
pub fn cast(self: Type, comptime T: type) ?*T {
- if (self.tag_if_small_enough < Tag.no_payload_count)
+ if (@hasField(T, "base_tag")) {
+ return base.castTag(T.base_tag);
+ }
+ if (self.tag_if_small_enough < Tag.no_payload_count) {
return null;
+ }
+ inline for (@typeInfo(Tag).Enum.fields) |field| {
+ if (field.value < Tag.no_payload_count)
+ continue;
+ const t = @intToEnum(Tag, field.value);
+ if (self.ptr_otherwise.tag == t) {
+ if (T == t.Type()) {
+ return @fieldParentPtr(T, "base", self.ptr_otherwise);
+ }
+ return null;
+ }
+ }
+ unreachable;
+ }
- const expected_tag = std.meta.fieldInfo(T, "base").default_value.?.tag;
- if (self.ptr_otherwise.tag != expected_tag)
+ pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() {
+ if (self.tag_if_small_enough < Tag.no_payload_count)
return null;
- return @fieldParentPtr(T, "base", self.ptr_otherwise);
+ if (self.ptr_otherwise.tag == t)
+ return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);
+
+ return null;
}
- pub fn castPointer(self: Type) ?*Payload.PointerSimple {
+ pub fn castPointer(self: Type) ?*Payload.ElemType {
return switch (self.tag()) {
.single_const_pointer,
.single_mut_pointer,
@@ -135,7 +162,11 @@ pub const Type = extern union {
.mut_slice,
.optional_single_const_pointer,
.optional_single_mut_pointer,
- => @fieldParentPtr(Payload.PointerSimple, "base", self.ptr_otherwise),
+ => self.cast(Payload.ElemType),
+
+ .inferred_alloc_const => unreachable,
+ .inferred_alloc_mut => unreachable,
+
else => null,
};
}
@@ -165,14 +196,22 @@ pub const Type = extern union {
// Hot path for common case:
if (a.castPointer()) |a_payload| {
if (b.castPointer()) |b_payload| {
- return a.tag() == b.tag() and eql(a_payload.pointee_type, b_payload.pointee_type);
+ return a.tag() == b.tag() and eql(a_payload.data, b_payload.data);
}
}
const is_slice_a = isSlice(a);
const is_slice_b = isSlice(b);
if (is_slice_a != is_slice_b)
return false;
- @panic("TODO implement more pointer Type equality comparison");
+
+ const ptr_size_a = ptrSize(a);
+ const ptr_size_b = ptrSize(b);
+ if (ptr_size_a != ptr_size_b)
+ return false;
+
+ std.debug.panic("TODO implement more pointer Type equality comparison: {} and {}", .{
+ a, b,
+ });
},
.Int => {
// Detect that e.g. u64 != usize, even if the bits match on a particular target.
@@ -222,8 +261,8 @@ pub const Type = extern union {
return true;
},
.Optional => {
- var buf_a: Payload.PointerSimple = undefined;
- var buf_b: Payload.PointerSimple = undefined;
+ var buf_a: Payload.ElemType = undefined;
+ var buf_b: Payload.ElemType = undefined;
return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b));
},
.Float,
@@ -286,7 +325,7 @@ pub const Type = extern union {
}
},
.Optional => {
- var buf: Payload.PointerSimple = undefined;
+ var buf: Payload.ElemType = undefined;
std.hash.autoHash(&hasher, self.optionalChild(&buf).hash());
},
.Float,
@@ -320,6 +359,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -354,70 +395,68 @@ pub const Type = extern union {
.enum_literal,
.anyerror_void_error_union,
.@"anyframe",
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
=> unreachable,
- .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
- .array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8),
+ .array_u8,
+ .array_u8_sentinel_0,
+ => return self.copyPayloadShallow(allocator, Payload.Len),
+
+ .single_const_pointer,
+ .single_mut_pointer,
+ .many_const_pointer,
+ .many_mut_pointer,
+ .c_const_pointer,
+ .c_mut_pointer,
+ .const_slice,
+ .mut_slice,
+ .optional,
+ .optional_single_mut_pointer,
+ .optional_single_const_pointer,
+ .anyframe_T,
+ => return self.copyPayloadShallow(allocator, Payload.ElemType),
+
+ .int_signed,
+ .int_unsigned,
+ => return self.copyPayloadShallow(allocator, Payload.Bits),
+
.array => {
- const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
- const new_payload = try allocator.create(Payload.Array);
- new_payload.* = .{
- .base = payload.base,
+ const payload = self.castTag(.array).?.data;
+ return Tag.array.create(allocator, .{
.len = payload.len,
.elem_type = try payload.elem_type.copy(allocator),
- };
- return Type{ .ptr_otherwise = &new_payload.base };
+ });
},
.array_sentinel => {
- const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
- const new_payload = try allocator.create(Payload.ArraySentinel);
- new_payload.* = .{
- .base = payload.base,
+ const payload = self.castTag(.array_sentinel).?.data;
+ return Tag.array_sentinel.create(allocator, .{
.len = payload.len,
.sentinel = try payload.sentinel.copy(allocator),
.elem_type = try payload.elem_type.copy(allocator),
- };
- return Type{ .ptr_otherwise = &new_payload.base };
+ });
},
- .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),
- .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),
.function => {
- const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise);
- const new_payload = try allocator.create(Payload.Function);
+ const payload = self.castTag(.function).?.data;
const param_types = try allocator.alloc(Type, payload.param_types.len);
for (payload.param_types) |param_type, i| {
param_types[i] = try param_type.copy(allocator);
}
- new_payload.* = .{
- .base = payload.base,
+ return Tag.function.create(allocator, .{
.return_type = try payload.return_type.copy(allocator),
.param_types = param_types,
.cc = payload.cc,
- };
- return Type{ .ptr_otherwise = &new_payload.base };
+ });
},
- .optional => return self.copyPayloadSingleField(allocator, Payload.Optional, "child_type"),
- .single_const_pointer,
- .single_mut_pointer,
- .many_const_pointer,
- .many_mut_pointer,
- .c_const_pointer,
- .c_mut_pointer,
- .const_slice,
- .mut_slice,
- .optional_single_mut_pointer,
- .optional_single_const_pointer,
- => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"),
- .anyframe_T => return self.copyPayloadSingleField(allocator, Payload.AnyFrame, "return_type"),
-
.pointer => {
- const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
- const new_payload = try allocator.create(Payload.Pointer);
- new_payload.* = .{
- .base = payload.base,
-
+ const payload = self.castTag(.pointer).?.data;
+ const sent: ?Value = if (payload.sentinel) |some|
+ try some.copy(allocator)
+ else
+ null;
+ return Tag.pointer.create(allocator, .{
.pointee_type = try payload.pointee_type.copy(allocator),
- .sentinel = if (payload.sentinel) |some| try some.copy(allocator) else null,
+ .sentinel = sent,
.@"align" = payload.@"align",
.bit_offset = payload.bit_offset,
.host_size = payload.host_size,
@@ -425,41 +464,33 @@ pub const Type = extern union {
.mutable = payload.mutable,
.@"volatile" = payload.@"volatile",
.size = payload.size,
- };
- return Type{ .ptr_otherwise = &new_payload.base };
+ });
},
.error_union => {
- const payload = @fieldParentPtr(Payload.ErrorUnion, "base", self.ptr_otherwise);
- const new_payload = try allocator.create(Payload.ErrorUnion);
- new_payload.* = .{
- .base = payload.base,
-
+ const payload = self.castTag(.error_union).?.data;
+ return Tag.error_union.create(allocator, .{
.error_set = try payload.error_set.copy(allocator),
.payload = try payload.payload.copy(allocator),
- };
- return Type{ .ptr_otherwise = &new_payload.base };
+ });
},
- .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
- .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),
- .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct),
+ .error_set => return self.copyPayloadShallow(allocator, Payload.Decl),
+ .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
+ .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),
+
+ .@"enum" => return self.copyPayloadShallow(allocator, Payload.Enum),
+ .@"struct" => return self.copyPayloadShallow(allocator, Payload.Struct),
+ .@"union" => return self.copyPayloadShallow(allocator, Payload.Union),
+ .@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),
}
}
fn copyPayloadShallow(self: Type, allocator: *Allocator, comptime T: type) error{OutOfMemory}!Type {
- const payload = @fieldParentPtr(T, "base", self.ptr_otherwise);
+ const payload = self.cast(T).?;
const new_payload = try allocator.create(T);
new_payload.* = payload.*;
return Type{ .ptr_otherwise = &new_payload.base };
}
- fn copyPayloadSingleField(self: Type, allocator: *Allocator, comptime T: type, comptime field_name: []const u8) error{OutOfMemory}!Type {
- const payload = @fieldParentPtr(T, "base", self.ptr_otherwise);
- const new_payload = try allocator.create(T);
- new_payload.base = payload.base;
- @field(new_payload, field_name) = try @field(payload, field_name).copy(allocator);
- return Type{ .ptr_otherwise = &new_payload.base };
- }
-
pub fn format(
self: Type,
comptime fmt: []const u8,
@@ -479,6 +510,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -519,120 +552,122 @@ pub const Type = extern union {
.fn_ccc_void_no_args => return out_stream.writeAll("fn() callconv(.C) void"),
.single_const_pointer_to_comptime_int => return out_stream.writeAll("*const comptime_int"),
.function => {
- const payload = @fieldParentPtr(Payload.Function, "base", ty.ptr_otherwise);
+ const payload = ty.castTag(.function).?.data;
try out_stream.writeAll("fn(");
for (payload.param_types) |param_type, i| {
if (i != 0) try out_stream.writeAll(", ");
try param_type.format("", .{}, out_stream);
}
- try out_stream.writeAll(") ");
+ try out_stream.writeAll(") callconv(.");
+ try out_stream.writeAll(@tagName(payload.cc));
+ try out_stream.writeAll(")");
ty = payload.return_type;
continue;
},
.anyframe_T => {
- const payload = @fieldParentPtr(Payload.AnyFrame, "base", ty.ptr_otherwise);
+ const return_type = ty.castTag(.anyframe_T).?.data;
try out_stream.print("anyframe->", .{});
- ty = payload.return_type;
+ ty = return_type;
continue;
},
.array_u8 => {
- const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);
- return out_stream.print("[{}]u8", .{payload.len});
+ const len = ty.castTag(.array_u8).?.data;
+ return out_stream.print("[{d}]u8", .{len});
},
.array_u8_sentinel_0 => {
- const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise);
- return out_stream.print("[{}:0]u8", .{payload.len});
+ const len = ty.castTag(.array_u8_sentinel_0).?.data;
+ return out_stream.print("[{d}:0]u8", .{len});
},
.array => {
- const payload = @fieldParentPtr(Payload.Array, "base", ty.ptr_otherwise);
- try out_stream.print("[{}]", .{payload.len});
+ const payload = ty.castTag(.array).?.data;
+ try out_stream.print("[{d}]", .{payload.len});
ty = payload.elem_type;
continue;
},
.array_sentinel => {
- const payload = @fieldParentPtr(Payload.ArraySentinel, "base", ty.ptr_otherwise);
- try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel });
+ const payload = ty.castTag(.array_sentinel).?.data;
+ try out_stream.print("[{d}:{}]", .{ payload.len, payload.sentinel });
ty = payload.elem_type;
continue;
},
.single_const_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.single_const_pointer).?.data;
try out_stream.writeAll("*const ");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.single_mut_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.single_mut_pointer).?.data;
try out_stream.writeAll("*");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.many_const_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.many_const_pointer).?.data;
try out_stream.writeAll("[*]const ");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.many_mut_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.many_mut_pointer).?.data;
try out_stream.writeAll("[*]");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.c_const_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.c_const_pointer).?.data;
try out_stream.writeAll("[*c]const ");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.c_mut_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.c_mut_pointer).?.data;
try out_stream.writeAll("[*c]");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.const_slice => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.const_slice).?.data;
try out_stream.writeAll("[]const ");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.mut_slice => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.mut_slice).?.data;
try out_stream.writeAll("[]");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.int_signed => {
- const payload = @fieldParentPtr(Payload.IntSigned, "base", ty.ptr_otherwise);
- return out_stream.print("i{}", .{payload.bits});
+ const bits = ty.castTag(.int_signed).?.data;
+ return out_stream.print("i{d}", .{bits});
},
.int_unsigned => {
- const payload = @fieldParentPtr(Payload.IntUnsigned, "base", ty.ptr_otherwise);
- return out_stream.print("u{}", .{payload.bits});
+ const bits = ty.castTag(.int_unsigned).?.data;
+ return out_stream.print("u{d}", .{bits});
},
.optional => {
- const payload = @fieldParentPtr(Payload.Optional, "base", ty.ptr_otherwise);
+ const child_type = ty.castTag(.optional).?.data;
try out_stream.writeByte('?');
- ty = payload.child_type;
+ ty = child_type;
continue;
},
.optional_single_const_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;
try out_stream.writeAll("?*const ");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.optional_single_mut_pointer => {
- const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);
+ const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;
try out_stream.writeAll("?*");
- ty = payload.pointee_type;
+ ty = pointee_type;
continue;
},
.pointer => {
- const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);
+ const payload = ty.castTag(.pointer).?.data;
if (payload.sentinel) |some| switch (payload.size) {
.One, .C => unreachable,
.Many => try out_stream.print("[*:{}]", .{some}),
@@ -644,10 +679,10 @@ pub const Type = extern union {
.Slice => try out_stream.writeAll("[]"),
}
if (payload.@"align" != 0) {
- try out_stream.print("align({}", .{payload.@"align"});
+ try out_stream.print("align({d}", .{payload.@"align"});
if (payload.bit_offset != 0) {
- try out_stream.print(":{}:{}", .{ payload.bit_offset, payload.host_size });
+ try out_stream.print(":{d}:{d}", .{ payload.bit_offset, payload.host_size });
}
try out_stream.writeAll(") ");
}
@@ -659,20 +694,27 @@ pub const Type = extern union {
continue;
},
.error_union => {
- const payload = @fieldParentPtr(Payload.ErrorUnion, "base", ty.ptr_otherwise);
+ const payload = ty.castTag(.error_union).?.data;
try payload.error_set.format("", .{}, out_stream);
try out_stream.writeAll("!");
ty = payload.payload;
continue;
},
.error_set => {
- const payload = @fieldParentPtr(Payload.ErrorSet, "base", ty.ptr_otherwise);
- return out_stream.writeAll(std.mem.spanZ(payload.decl.name));
+ const decl = ty.castTag(.error_set).?.data;
+ return out_stream.writeAll(std.mem.spanZ(decl.name));
},
.error_set_single => {
- const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise);
- return out_stream.print("error{{{}}}", .{payload.name});
+ const name = ty.castTag(.error_set_single).?.data;
+ return out_stream.print("error{{{s}}}", .{name});
},
+ .inferred_alloc_const => return out_stream.writeAll("(inferred_alloc_const)"),
+ .inferred_alloc_mut => return out_stream.writeAll("(inferred_alloc_mut)"),
+ // TODO use declaration name
+ .@"enum" => return out_stream.writeAll("enum {}"),
+ .@"struct" => return out_stream.writeAll("struct {}"),
+ .@"union" => return out_stream.writeAll("union {}"),
+ .@"opaque" => return out_stream.writeAll("opaque {}"),
}
unreachable;
}
@@ -720,11 +762,9 @@ pub const Type = extern union {
.single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
.const_slice_u8 => return Value.initTag(.const_slice_u8_type),
.enum_literal => return Value.initTag(.enum_literal_type),
- else => {
- const ty_payload = try allocator.create(Value.Payload.Ty);
- ty_payload.* = .{ .ty = self };
- return Value.initPayload(&ty_payload.base);
- },
+ .inferred_alloc_const => unreachable,
+ .inferred_alloc_mut => unreachable,
+ else => return Value.Tag.ty.create(allocator, self),
}
}
@@ -738,6 +778,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -776,14 +818,17 @@ pub const Type = extern union {
.array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
.array_u8 => self.arrayLen() != 0,
.array_sentinel, .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, .const_slice, .mut_slice, .pointer => self.elemType().hasCodeGenBits(),
- .int_signed => self.cast(Payload.IntSigned).?.bits != 0,
- .int_unsigned => self.cast(Payload.IntUnsigned).?.bits != 0,
+ .int_signed, .int_unsigned => self.cast(Payload.Bits).?.data != 0,
.error_union => {
- const payload = self.cast(Payload.ErrorUnion).?;
+ const payload = self.castTag(.error_union).?.data;
return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
},
+ .@"enum" => @panic("TODO"),
+ .@"struct" => @panic("TODO"),
+ .@"union" => @panic("TODO"),
+
.c_void,
.void,
.type,
@@ -794,7 +839,11 @@ pub const Type = extern union {
.@"undefined",
.enum_literal,
.empty_struct,
+ .@"opaque",
=> false,
+
+ .inferred_alloc_const => unreachable,
+ .inferred_alloc_mut => unreachable,
};
}
@@ -827,6 +876,7 @@ pub const Type = extern union {
.i16, .u16 => return 2,
.i32, .u32 => return 4,
.i64, .u64 => return 8,
+ .u128, .i128 => return 16,
.isize,
.usize,
@@ -847,7 +897,7 @@ pub const Type = extern union {
=> return @divExact(target.cpu.arch.ptrBitWidth(), 8),
.pointer => {
- const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
+ const payload = self.castTag(.pointer).?.data;
if (payload.@"align" != 0) return payload.@"align";
return @divExact(target.cpu.arch.ptrBitWidth(), 8);
@@ -877,18 +927,12 @@ pub const Type = extern union {
.array, .array_sentinel => return self.elemType().abiAlignment(target),
.int_signed, .int_unsigned => {
- const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
- pl.bits
- else if (self.cast(Payload.IntUnsigned)) |pl|
- pl.bits
- else
- unreachable;
-
+ const bits: u16 = self.cast(Payload.Bits).?.data;
return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
},
.optional => {
- var buf: Payload.PointerSimple = undefined;
+ var buf: Payload.ElemType = undefined;
const child_type = self.optionalChild(&buf);
if (!child_type.hasCodeGenBits()) return 1;
@@ -899,7 +943,7 @@ pub const Type = extern union {
},
.error_union => {
- const payload = self.cast(Payload.ErrorUnion).?;
+ const payload = self.castTag(.error_union).?.data;
if (!payload.error_set.hasCodeGenBits()) {
return payload.payload.abiAlignment(target);
} else if (!payload.payload.hasCodeGenBits()) {
@@ -908,6 +952,10 @@ pub const Type = extern union {
@panic("TODO abiAlignment error union");
},
+ .@"enum" => self.cast(Payload.Enum).?.abiAlignment(target),
+ .@"struct" => @panic("TODO"),
+ .@"union" => @panic("TODO"),
+
.c_void,
.void,
.type,
@@ -918,6 +966,9 @@ pub const Type = extern union {
.@"undefined",
.enum_literal,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"opaque",
=> unreachable,
};
}
@@ -941,27 +992,34 @@ pub const Type = extern union {
.enum_literal => unreachable,
.single_const_pointer_to_comptime_int => unreachable,
.empty_struct => unreachable,
+ .inferred_alloc_const => unreachable,
+ .inferred_alloc_mut => unreachable,
+ .@"opaque" => unreachable,
.u8,
.i8,
.bool,
=> return 1,
- .array_u8 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,
- .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len + 1,
+ .array_u8 => self.castTag(.array_u8).?.data,
+ .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data + 1,
.array => {
- const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
+ const payload = self.castTag(.array).?.data;
const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
return payload.len * elem_size;
},
.array_sentinel => {
- const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
- const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
+ const payload = self.castTag(.array_sentinel).?.data;
+ const elem_size = std.math.max(
+ payload.elem_type.abiAlignment(target),
+ payload.elem_type.abiSize(target),
+ );
return (payload.len + 1) * elem_size;
},
.i16, .u16 => return 2,
.i32, .u32 => return 4,
.i64, .u64 => return 8,
+ .u128, .i128 => return 16,
.@"anyframe", .anyframe_T, .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
@@ -1014,18 +1072,12 @@ pub const Type = extern union {
=> return 2, // TODO revisit this when we have the concept of the error tag type
.int_signed, .int_unsigned => {
- const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
- pl.bits
- else if (self.cast(Payload.IntUnsigned)) |pl|
- pl.bits
- else
- unreachable;
-
+ const bits: u16 = self.cast(Payload.Bits).?.data;
return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
},
.optional => {
- var buf: Payload.PointerSimple = undefined;
+ var buf: Payload.ElemType = undefined;
const child_type = self.optionalChild(&buf);
if (!child_type.hasCodeGenBits()) return 1;
@@ -1040,7 +1092,7 @@ pub const Type = extern union {
},
.error_union => {
- const payload = self.cast(Payload.ErrorUnion).?;
+ const payload = self.castTag(.error_union).?.data;
if (!payload.error_set.hasCodeGenBits() and !payload.payload.hasCodeGenBits()) {
return 0;
} else if (!payload.error_set.hasCodeGenBits()) {
@@ -1050,6 +1102,10 @@ pub const Type = extern union {
}
@panic("TODO abiSize error union");
},
+
+ .@"enum" => @panic("TODO"),
+ .@"struct" => @panic("TODO"),
+ .@"union" => @panic("TODO"),
};
}
@@ -1063,6 +1119,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -1117,14 +1175,110 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
=> true,
- .pointer => self.cast(Payload.Pointer).?.size == .One,
+ .pointer => self.castTag(.pointer).?.data.size == .One,
+ };
+ }
+
+ /// Asserts the `Type` is a pointer.
+ pub fn ptrSize(self: Type) std.builtin.TypeInfo.Pointer.Size {
+ return switch (self.tag()) {
+ .u8,
+ .i8,
+ .u16,
+ .i16,
+ .u32,
+ .i32,
+ .u64,
+ .i64,
+ .u128,
+ .i128,
+ .usize,
+ .isize,
+ .c_short,
+ .c_ushort,
+ .c_int,
+ .c_uint,
+ .c_long,
+ .c_ulong,
+ .c_longlong,
+ .c_ulonglong,
+ .c_longdouble,
+ .f16,
+ .f32,
+ .f64,
+ .f128,
+ .c_void,
+ .bool,
+ .void,
+ .type,
+ .anyerror,
+ .comptime_int,
+ .comptime_float,
+ .noreturn,
+ .@"null",
+ .@"undefined",
+ .array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
+ .fn_noreturn_no_args,
+ .fn_void_no_args,
+ .fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
+ .function,
+ .int_unsigned,
+ .int_signed,
+ .optional,
+ .optional_single_mut_pointer,
+ .optional_single_const_pointer,
+ .enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
+ .error_set,
+ .error_set_single,
+ .empty_struct,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
+ => unreachable,
+
+ .const_slice,
+ .mut_slice,
+ .const_slice_u8,
+ => .Slice,
+
+ .many_const_pointer,
+ .many_mut_pointer,
+ => .Many,
+
+ .c_const_pointer,
+ .c_mut_pointer,
+ => .C,
+
+ .single_const_pointer,
+ .single_mut_pointer,
+ .single_const_pointer_to_comptime_int,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ => .One,
+
+ .pointer => self.castTag(.pointer).?.data.size,
};
}
@@ -1138,6 +1292,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -1192,6 +1348,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.const_slice,
@@ -1199,7 +1361,7 @@ pub const Type = extern union {
.const_slice_u8,
=> true,
- .pointer => self.cast(Payload.Pointer).?.size == .Slice,
+ .pointer => self.castTag(.pointer).?.data.size == .Slice,
};
}
@@ -1213,6 +1375,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -1264,6 +1428,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.single_const_pointer,
@@ -1274,7 +1444,7 @@ pub const Type = extern union {
.const_slice,
=> true,
- .pointer => !self.cast(Payload.Pointer).?.mutable,
+ .pointer => !self.castTag(.pointer).?.data.mutable,
};
}
@@ -1288,6 +1458,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -1345,10 +1517,16 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.pointer => {
- const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
+ const payload = self.castTag(.pointer).?.data;
return payload.@"volatile";
},
};
@@ -1364,6 +1542,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -1421,10 +1601,16 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.pointer => {
- const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
+ const payload = self.castTag(.pointer).?.data;
return payload.@"allowzero";
},
};
@@ -1435,7 +1621,7 @@ pub const Type = extern union {
switch (self.tag()) {
.optional_single_const_pointer, .optional_single_mut_pointer => return true,
.optional => {
- var buf: Payload.PointerSimple = undefined;
+ var buf: Payload.ElemType = undefined;
const child_type = self.optionalChild(&buf);
// optionals of zero sized pointers behave like bools
if (!child_type.hasCodeGenBits()) return false;
@@ -1473,7 +1659,7 @@ pub const Type = extern union {
=> return false,
.Optional => {
- var buf: Payload.PointerSimple = undefined;
+ var buf: Payload.ElemType = undefined;
return ty.optionalChild(&buf).isValidVarType(is_extern);
},
.Pointer, .Array => ty = ty.elemType(),
@@ -1488,61 +1674,68 @@ pub const Type = extern union {
/// Asserts the type is a pointer or array type.
pub fn elemType(self: Type) Type {
return switch (self.tag()) {
- .u8,
- .i8,
- .u16,
- .i16,
- .u32,
- .i32,
- .u64,
- .i64,
- .usize,
- .isize,
- .c_short,
- .c_ushort,
- .c_int,
- .c_uint,
- .c_long,
- .c_ulong,
- .c_longlong,
- .c_ulonglong,
- .c_longdouble,
- .f16,
- .f32,
- .f64,
- .f128,
- .c_void,
- .bool,
- .void,
- .type,
- .anyerror,
- .comptime_int,
- .comptime_float,
- .noreturn,
- .@"null",
- .@"undefined",
- .fn_noreturn_no_args,
- .fn_void_no_args,
- .fn_naked_noreturn_no_args,
- .fn_ccc_void_no_args,
- .function,
- .int_unsigned,
- .int_signed,
- .optional,
- .optional_single_const_pointer,
- .optional_single_mut_pointer,
- .enum_literal,
- .error_union,
- .@"anyframe",
- .anyframe_T,
- .anyerror_void_error_union,
- .error_set,
- .error_set_single,
- .empty_struct,
- => unreachable,
-
- .array => self.cast(Payload.Array).?.elem_type,
- .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type,
+ .u8 => unreachable,
+ .i8 => unreachable,
+ .u16 => unreachable,
+ .i16 => unreachable,
+ .u32 => unreachable,
+ .i32 => unreachable,
+ .u64 => unreachable,
+ .i64 => unreachable,
+ .u128 => unreachable,
+ .i128 => unreachable,
+ .usize => unreachable,
+ .isize => unreachable,
+ .c_short => unreachable,
+ .c_ushort => unreachable,
+ .c_int => unreachable,
+ .c_uint => unreachable,
+ .c_long => unreachable,
+ .c_ulong => unreachable,
+ .c_longlong => unreachable,
+ .c_ulonglong => unreachable,
+ .c_longdouble => unreachable,
+ .f16 => unreachable,
+ .f32 => unreachable,
+ .f64 => unreachable,
+ .f128 => unreachable,
+ .c_void => unreachable,
+ .bool => unreachable,
+ .void => unreachable,
+ .type => unreachable,
+ .anyerror => unreachable,
+ .comptime_int => unreachable,
+ .comptime_float => unreachable,
+ .noreturn => unreachable,
+ .@"null" => unreachable,
+ .@"undefined" => unreachable,
+ .fn_noreturn_no_args => unreachable,
+ .fn_void_no_args => unreachable,
+ .fn_naked_noreturn_no_args => unreachable,
+ .fn_ccc_void_no_args => unreachable,
+ .function => unreachable,
+ .int_unsigned => unreachable,
+ .int_signed => unreachable,
+ .optional => unreachable,
+ .optional_single_const_pointer => unreachable,
+ .optional_single_mut_pointer => unreachable,
+ .enum_literal => unreachable,
+ .error_union => unreachable,
+ .@"anyframe" => unreachable,
+ .anyframe_T => unreachable,
+ .anyerror_void_error_union => unreachable,
+ .error_set => unreachable,
+ .error_set_single => unreachable,
+ .empty_struct => unreachable,
+ .inferred_alloc_const => unreachable,
+ .inferred_alloc_mut => unreachable,
+ .@"enum" => unreachable,
+ .@"struct" => unreachable,
+ .@"union" => unreachable,
+ .@"opaque" => unreachable,
+
+ .array => self.castTag(.array).?.data.elem_type,
+ .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,
.single_const_pointer,
.single_mut_pointer,
.many_const_pointer,
@@ -1551,28 +1744,29 @@ pub const Type = extern union {
.c_mut_pointer,
.const_slice,
.mut_slice,
- => self.castPointer().?.pointee_type,
+ => self.castPointer().?.data,
.array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
.single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
- .pointer => self.cast(Payload.Pointer).?.pointee_type,
+ .pointer => self.castTag(.pointer).?.data.pointee_type,
};
}
/// Asserts that the type is an optional.
- pub fn optionalChild(self: Type, buf: *Payload.PointerSimple) Type {
+ /// Resulting `Type` will have inner memory referencing `buf`.
+ pub fn optionalChild(self: Type, buf: *Payload.ElemType) Type {
return switch (self.tag()) {
- .optional => self.cast(Payload.Optional).?.child_type,
+ .optional => self.castTag(.optional).?.data,
.optional_single_mut_pointer => {
buf.* = .{
.base = .{ .tag = .single_mut_pointer },
- .pointee_type = self.castPointer().?.pointee_type,
+ .data = self.castPointer().?.data,
};
return Type.initPayload(&buf.base);
},
.optional_single_const_pointer => {
buf.* = .{
.base = .{ .tag = .single_const_pointer },
- .pointee_type = self.castPointer().?.pointee_type,
+ .data = self.castPointer().?.data,
};
return Type.initPayload(&buf.base);
},
@@ -1583,23 +1777,16 @@ pub const Type = extern union {
/// Asserts that the type is an optional.
/// Same as `optionalChild` but allocates the buffer if needed.
pub fn optionalChildAlloc(self: Type, allocator: *Allocator) !Type {
- return switch (self.tag()) {
- .optional => self.cast(Payload.Optional).?.child_type,
- .optional_single_mut_pointer, .optional_single_const_pointer => {
- const payload = try allocator.create(Payload.PointerSimple);
- payload.* = .{
- .base = .{
- .tag = if (self.tag() == .optional_single_const_pointer)
- .single_const_pointer
- else
- .single_mut_pointer,
- },
- .pointee_type = self.castPointer().?.pointee_type,
- };
- return Type.initPayload(&payload.base);
+ switch (self.tag()) {
+ .optional => return self.castTag(.optional).?.data,
+ .optional_single_mut_pointer => {
+ return Tag.single_mut_pointer.create(allocator, self.castPointer().?.data);
+ },
+ .optional_single_const_pointer => {
+ return Tag.single_const_pointer.create(allocator, self.castPointer().?.data);
},
else => unreachable,
- };
+ }
}
/// Asserts the type is an array or vector.
@@ -1613,6 +1800,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -1667,12 +1856,18 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
- .array => self.cast(Payload.Array).?.len,
- .array_sentinel => self.cast(Payload.ArraySentinel).?.len,
- .array_u8 => self.cast(Payload.Array_u8).?.len,
- .array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len,
+ .array => self.castTag(.array).?.data.len,
+ .array_sentinel => self.castTag(.array_sentinel).?.data.len,
+ .array_u8 => self.castTag(.array_u8).?.data,
+ .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data,
};
}
@@ -1687,6 +1882,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -1733,6 +1930,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
.single_const_pointer,
@@ -1746,8 +1949,8 @@ pub const Type = extern union {
.array_u8,
=> return null,
- .pointer => return self.cast(Payload.Pointer).?.sentinel,
- .array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel,
+ .pointer => return self.castTag(.pointer).?.data.sentinel,
+ .array_sentinel => return self.castTag(.array_sentinel).?.data.sentinel,
.array_u8_sentinel_0 => return Value.initTag(.zero),
};
}
@@ -1816,6 +2019,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.int_signed,
@@ -1828,6 +2037,8 @@ pub const Type = extern union {
.i16,
.i32,
.i64,
+ .u128,
+ .i128,
=> true,
};
}
@@ -1880,6 +2091,8 @@ pub const Type = extern union {
.i16,
.i32,
.i64,
+ .u128,
+ .i128,
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
@@ -1891,6 +2104,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.int_unsigned,
@@ -1956,10 +2175,22 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
- .int_unsigned => .{ .signedness = .unsigned, .bits = self.cast(Payload.IntUnsigned).?.bits },
- .int_signed => .{ .signedness = .signed, .bits = self.cast(Payload.IntSigned).?.bits },
+ .int_unsigned => .{
+ .signedness = .unsigned,
+ .bits = self.castTag(.int_unsigned).?.data,
+ },
+ .int_signed => .{
+ .signedness = .signed,
+ .bits = self.castTag(.int_signed).?.data,
+ },
.u8 => .{ .signedness = .unsigned, .bits = 8 },
.i8 => .{ .signedness = .signed, .bits = 8 },
.u16 => .{ .signedness = .unsigned, .bits = 16 },
@@ -1968,6 +2199,8 @@ pub const Type = extern union {
.i32 => .{ .signedness = .signed, .bits = 32 },
.u64 => .{ .signedness = .unsigned, .bits = 64 },
.i64 => .{ .signedness = .signed, .bits = 64 },
+ .u128 => .{ .signedness = .unsigned, .bits = 128 },
+ .i128 => .{ .signedness = .signed, .bits = 128 },
.usize => .{ .signedness = .unsigned, .bits = target.cpu.arch.ptrBitWidth() },
.isize => .{ .signedness = .signed, .bits = target.cpu.arch.ptrBitWidth() },
.c_short => .{ .signedness = .signed, .bits = CType.short.sizeInBits(target) },
@@ -2028,6 +2261,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
@@ -2039,6 +2274,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
.usize,
@@ -2088,7 +2329,7 @@ pub const Type = extern union {
.fn_void_no_args => 0,
.fn_naked_noreturn_no_args => 0,
.fn_ccc_void_no_args => 0,
- .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).param_types.len,
+ .function => self.castTag(.function).?.data.param_types.len,
.f16,
.f32,
@@ -2128,6 +2369,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2151,6 +2394,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
};
}
@@ -2164,7 +2413,7 @@ pub const Type = extern union {
.fn_naked_noreturn_no_args => return,
.fn_ccc_void_no_args => return,
.function => {
- const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise);
+ const payload = self.castTag(.function).?.data;
std.mem.copy(Type, types, payload.param_types);
},
@@ -2206,6 +2455,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2229,6 +2480,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
}
}
@@ -2237,7 +2494,7 @@ pub const Type = extern union {
pub fn fnParamType(self: Type, index: usize) Type {
switch (self.tag()) {
.function => {
- const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise);
+ const payload = self.castTag(.function).?.data;
return payload.param_types[index];
},
@@ -2283,6 +2540,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2306,6 +2565,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
}
}
@@ -2320,7 +2585,7 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
=> Type.initTag(.void),
- .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).return_type,
+ .function => self.castTag(.function).?.data.return_type,
.f16,
.f32,
@@ -2360,6 +2625,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2383,6 +2650,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
};
}
@@ -2394,7 +2667,7 @@ pub const Type = extern union {
.fn_void_no_args => .Unspecified,
.fn_naked_noreturn_no_args => .Naked,
.fn_ccc_void_no_args => .C,
- .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).cc,
+ .function => self.castTag(.function).?.data.cc,
.f16,
.f32,
@@ -2434,6 +2707,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2457,6 +2732,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
};
}
@@ -2508,6 +2789,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2531,6 +2814,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> unreachable,
};
}
@@ -2552,6 +2841,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2605,6 +2896,12 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> false,
};
}
@@ -2627,6 +2924,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2662,23 +2961,21 @@ pub const Type = extern union {
.error_union,
.error_set,
.error_set_single,
+ .@"opaque",
=> return null,
+ .@"enum" => @panic("TODO onePossibleValue enum"),
+ .@"struct" => @panic("TODO onePossibleValue struct"),
+ .@"union" => @panic("TODO onePossibleValue union"),
+
.empty_struct => return Value.initTag(.empty_struct_value),
.void => return Value.initTag(.void_value),
.noreturn => return Value.initTag(.unreachable_value),
.@"null" => return Value.initTag(.null_value),
.@"undefined" => return Value.initTag(.undef),
- .int_unsigned => {
- if (ty.cast(Payload.IntUnsigned).?.bits == 0) {
- return Value.initTag(.zero);
- } else {
- return null;
- }
- },
- .int_signed => {
- if (ty.cast(Payload.IntSigned).?.bits == 0) {
+ .int_unsigned, .int_signed => {
+ if (ty.cast(Payload.Bits).?.data == 0) {
return Value.initTag(.zero);
} else {
return null;
@@ -2697,14 +2994,15 @@ pub const Type = extern union {
.single_const_pointer,
.single_mut_pointer,
=> {
- const ptr = ty.castPointer().?;
- ty = ptr.pointee_type;
+ ty = ty.castPointer().?.data;
continue;
},
.pointer => {
- ty = ty.cast(Payload.Pointer).?.pointee_type;
+ ty = ty.castTag(.pointer).?.data.pointee_type;
continue;
},
+ .inferred_alloc_const => unreachable,
+ .inferred_alloc_mut => unreachable,
};
}
@@ -2725,6 +3023,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2773,13 +3073,19 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.empty_struct,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .@"opaque",
=> return false,
.c_const_pointer,
.c_mut_pointer,
=> return true,
- .pointer => self.cast(Payload.Pointer).?.size == .C,
+ .pointer => self.castTag(.pointer).?.data.size == .C,
};
}
@@ -2808,6 +3114,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
+ .u128,
+ .i128,
.usize,
.isize,
.c_short,
@@ -2858,9 +3166,15 @@ pub const Type = extern union {
.c_const_pointer,
.c_mut_pointer,
.pointer,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
=> unreachable,
- .empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope,
+ .empty_struct => self.castTag(.empty_struct).?.data,
+ .@"enum" => &self.castTag(.@"enum").?.scope,
+ .@"struct" => &self.castTag(.@"struct").?.scope,
+ .@"union" => &self.castTag(.@"union").?.scope,
+ .@"opaque" => &self.castTag(.@"opaque").?.scope,
};
}
@@ -2874,11 +3188,8 @@ pub const Type = extern union {
}
if ((info.bits - 1) <= std.math.maxInt(u6)) {
- const payload = try arena.allocator.create(Value.Payload.Int_i64);
- payload.* = .{
- .int = -(@as(i64, 1) << @truncate(u6, info.bits - 1)),
- };
- return Value.initPayload(&payload.base);
+ const n: i64 = -(@as(i64, 1) << @truncate(u6, info.bits - 1));
+ return Value.Tag.int_i64.create(&arena.allocator, n);
}
var res = try std.math.big.int.Managed.initSet(&arena.allocator, 1);
@@ -2887,13 +3198,9 @@ pub const Type = extern union {
const res_const = res.toConst();
if (res_const.positive) {
- const val_payload = try arena.allocator.create(Value.Payload.IntBigPositive);
- val_payload.* = .{ .limbs = res_const.limbs };
- return Value.initPayload(&val_payload.base);
+ return Value.Tag.int_big_positive.create(&arena.allocator, res_const.limbs);
} else {
- const val_payload = try arena.allocator.create(Value.Payload.IntBigNegative);
- val_payload.* = .{ .limbs = res_const.limbs };
- return Value.initPayload(&val_payload.base);
+ return Value.Tag.int_big_negative.create(&arena.allocator, res_const.limbs);
}
}
@@ -2903,17 +3210,11 @@ pub const Type = extern union {
const info = self.intInfo(target);
if (info.signedness == .signed and (info.bits - 1) <= std.math.maxInt(u6)) {
- const payload = try arena.allocator.create(Value.Payload.Int_i64);
- payload.* = .{
- .int = (@as(i64, 1) << @truncate(u6, info.bits - 1)) - 1,
- };
- return Value.initPayload(&payload.base);
+ const n: i64 = (@as(i64, 1) << @truncate(u6, info.bits - 1)) - 1;
+ return Value.Tag.int_i64.create(&arena.allocator, n);
} else if (info.signedness == .signed and info.bits <= std.math.maxInt(u6)) {
- const payload = try arena.allocator.create(Value.Payload.Int_u64);
- payload.* = .{
- .int = (@as(u64, 1) << @truncate(u6, info.bits)) - 1,
- };
- return Value.initPayload(&payload.base);
+ const n: u64 = (@as(u64, 1) << @truncate(u6, info.bits)) - 1;
+ return Value.Tag.int_u64.create(&arena.allocator, n);
}
var res = try std.math.big.int.Managed.initSet(&arena.allocator, 1);
@@ -2926,13 +3227,9 @@ pub const Type = extern union {
const res_const = res.toConst();
if (res_const.positive) {
- const val_payload = try arena.allocator.create(Value.Payload.IntBigPositive);
- val_payload.* = .{ .limbs = res_const.limbs };
- return Value.initPayload(&val_payload.base);
+ return Value.Tag.int_big_positive.create(&arena.allocator, res_const.limbs);
} else {
- const val_payload = try arena.allocator.create(Value.Payload.IntBigNegative);
- val_payload.* = .{ .limbs = res_const.limbs };
- return Value.initPayload(&val_payload.base);
+ return Value.Tag.int_big_negative.create(&arena.allocator, res_const.limbs);
}
}
@@ -2952,6 +3249,8 @@ pub const Type = extern union {
i32,
u64,
i64,
+ u128,
+ i128,
usize,
isize,
c_short,
@@ -2985,7 +3284,13 @@ pub const Type = extern union {
single_const_pointer_to_comptime_int,
anyerror_void_error_union,
@"anyframe",
- const_slice_u8, // See last_no_payload_tag below.
+ const_slice_u8,
+ /// This is a special value that tracks a set of types that have been stored
+ /// to an inferred allocation. It does not support most of the normal type queries.
+ /// However it does respond to `isConstPtr`, `ptrSize`, `zigTypeTag`, etc.
+ inferred_alloc_mut,
+ /// Same as `inferred_alloc_mut` but the local is `var` not `const`.
+ inferred_alloc_const, // See last_no_payload_tag below.
// After this, the tag requires a payload.
array_u8,
@@ -3012,121 +3317,226 @@ pub const Type = extern union {
error_set,
error_set_single,
empty_struct,
+ @"enum",
+ @"struct",
+ @"union",
+ @"opaque",
- pub const last_no_payload_tag = Tag.const_slice_u8;
+ pub const last_no_payload_tag = Tag.inferred_alloc_const;
pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
- };
- pub const Payload = struct {
- tag: Tag,
+ pub fn Type(comptime t: Tag) type {
+ return switch (t) {
+ .u8,
+ .i8,
+ .u16,
+ .i16,
+ .u32,
+ .i32,
+ .u64,
+ .i64,
+ .u128,
+ .i128,
+ .usize,
+ .isize,
+ .c_short,
+ .c_ushort,
+ .c_int,
+ .c_uint,
+ .c_long,
+ .c_ulong,
+ .c_longlong,
+ .c_ulonglong,
+ .c_longdouble,
+ .f16,
+ .f32,
+ .f64,
+ .f128,
+ .c_void,
+ .bool,
+ .void,
+ .type,
+ .anyerror,
+ .comptime_int,
+ .comptime_float,
+ .noreturn,
+ .enum_literal,
+ .@"null",
+ .@"undefined",
+ .fn_noreturn_no_args,
+ .fn_void_no_args,
+ .fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
+ .single_const_pointer_to_comptime_int,
+ .anyerror_void_error_union,
+ .@"anyframe",
+ .const_slice_u8,
+ .inferred_alloc_const,
+ .inferred_alloc_mut,
+ => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
+
+ .array_u8,
+ .array_u8_sentinel_0,
+ => Payload.Len,
+
+ .single_const_pointer,
+ .single_mut_pointer,
+ .many_const_pointer,
+ .many_mut_pointer,
+ .c_const_pointer,
+ .c_mut_pointer,
+ .const_slice,
+ .mut_slice,
+ .optional,
+ .optional_single_mut_pointer,
+ .optional_single_const_pointer,
+ .anyframe_T,
+ => Payload.ElemType,
+
+ .int_signed,
+ .int_unsigned,
+ => Payload.Bits,
+
+ .array => Payload.Array,
+ .array_sentinel => Payload.ArraySentinel,
+ .pointer => Payload.Pointer,
+ .function => Payload.Function,
+ .error_union => Payload.ErrorUnion,
+ .error_set => Payload.Decl,
+ .error_set_single => Payload.Name,
+ .empty_struct => Payload.ContainerScope,
+ .@"enum" => Payload.Enum,
+ .@"struct" => Payload.Struct,
+ .@"union" => Payload.Union,
+ .@"opaque" => Payload.Opaque,
+ };
+ }
- pub const Array_u8_Sentinel0 = struct {
- base: Payload = Payload{ .tag = .array_u8_sentinel_0 },
+ pub fn init(comptime t: Tag) Type {
+ comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
+ return .{ .tag_if_small_enough = @enumToInt(t) };
+ }
- len: u64,
- };
+ pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type {
+ const ptr = try ally.create(t.Type());
+ ptr.* = .{
+ .base = .{ .tag = t },
+ .data = data,
+ };
+ return Type{ .ptr_otherwise = &ptr.base };
+ }
- pub const Array_u8 = struct {
- base: Payload = Payload{ .tag = .array_u8 },
+ pub fn Data(comptime t: Tag) type {
+ return std.meta.fieldInfo(t.Type(), .data).field_type;
+ }
+ };
- len: u64,
+ /// The sub-types are named after what fields they contain.
+ pub const Payload = struct {
+ tag: Tag,
+
+ pub const Len = struct {
+ base: Payload,
+ data: u64,
};
pub const Array = struct {
- base: Payload = Payload{ .tag = .array },
+ pub const base_tag = Tag.array;
- len: u64,
- elem_type: Type,
+ base: Payload = Payload{ .tag = base_tag },
+ data: struct {
+ len: u64,
+ elem_type: Type,
+ },
};
pub const ArraySentinel = struct {
- base: Payload = Payload{ .tag = .array_sentinel },
+ pub const base_tag = Tag.array_sentinel;
- len: u64,
- sentinel: Value,
- elem_type: Type,
+ base: Payload = Payload{ .tag = base_tag },
+ data: struct {
+ len: u64,
+ sentinel: Value,
+ elem_type: Type,
+ },
};
- pub const PointerSimple = struct {
+ pub const ElemType = struct {
base: Payload,
-
- pointee_type: Type,
- };
-
- pub const IntSigned = struct {
- base: Payload = Payload{ .tag = .int_signed },
-
- bits: u16,
+ data: Type,
};
- pub const IntUnsigned = struct {
- base: Payload = Payload{ .tag = .int_unsigned },
-
- bits: u16,
+ pub const Bits = struct {
+ base: Payload,
+ data: u16,
};
pub const Function = struct {
- base: Payload = Payload{ .tag = .function },
-
- param_types: []Type,
- return_type: Type,
- cc: std.builtin.CallingConvention,
- };
-
- pub const Optional = struct {
- base: Payload = Payload{ .tag = .optional },
+ pub const base_tag = Tag.function;
- child_type: Type,
+ base: Payload = Payload{ .tag = base_tag },
+ data: struct {
+ param_types: []Type,
+ return_type: Type,
+ cc: std.builtin.CallingConvention,
+ },
};
pub const Pointer = struct {
- base: Payload = .{ .tag = .pointer },
-
- pointee_type: Type,
- sentinel: ?Value,
- /// If zero use pointee_type.AbiAlign()
- @"align": u32,
- bit_offset: u16,
- host_size: u16,
- @"allowzero": bool,
- mutable: bool,
- @"volatile": bool,
- size: std.builtin.TypeInfo.Pointer.Size,
+ pub const base_tag = Tag.pointer;
+
+ base: Payload = Payload{ .tag = base_tag },
+ data: struct {
+ pointee_type: Type,
+ sentinel: ?Value,
+ /// If zero use pointee_type.AbiAlign()
+ @"align": u32,
+ bit_offset: u16,
+ host_size: u16,
+ @"allowzero": bool,
+ mutable: bool,
+ @"volatile": bool,
+ size: std.builtin.TypeInfo.Pointer.Size,
+ },
};
pub const ErrorUnion = struct {
- base: Payload = .{ .tag = .error_union },
-
- error_set: Type,
- payload: Type,
- };
-
- pub const AnyFrame = struct {
- base: Payload = .{ .tag = .anyframe_T },
+ pub const base_tag = Tag.error_union;
- return_type: Type,
+ base: Payload = Payload{ .tag = base_tag },
+ data: struct {
+ error_set: Type,
+ payload: Type,
+ },
};
- pub const ErrorSet = struct {
- base: Payload = .{ .tag = .error_set },
-
- decl: *Module.Decl,
+ pub const Decl = struct {
+ base: Payload,
+ data: *Module.Decl,
};
- pub const ErrorSetSingle = struct {
- base: Payload = .{ .tag = .error_set_single },
-
+ pub const Name = struct {
+ base: Payload,
/// memory is owned by `Module`
- name: []const u8,
+ data: []const u8,
};
/// Mostly used for namespace like structs with zero fields.
/// Most commonly used for files.
- pub const EmptyStruct = struct {
- base: Payload = .{ .tag = .empty_struct },
+ pub const ContainerScope = struct {
+ base: Payload,
+ data: *Module.Scope.Container,
+ };
- scope: *Module.Scope.Container,
+ pub const Opaque = struct {
+ base: Payload = .{ .tag = .@"opaque" },
+
+ scope: Module.Scope.Container,
};
+
+ pub const Enum = @import("type/Enum.zig");
+ pub const Struct = @import("type/Struct.zig");
+ pub const Union = @import("type/Union.zig");
};
};
@@ -3254,6 +3664,9 @@ pub const CType = enum {
.amdpal,
.hermit,
.hurd,
+ .opencl,
+ .glsl450,
+ .vulkan,
=> @panic("TODO specify the C integer and float type sizes for this OS"),
}
}