aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-03-12 18:05:27 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-03-12 18:05:27 -0700
commit1f34c03ac14ac352ec03267ca8592dadfbd5e4bc (patch)
treeebcb851922636b7dd2b17acb72187836c86180ec /src/type.zig
parent868253a9c94d9907fae81e5e3108c7d10a85f5c3 (diff)
parent8ebb18d9da0bfbe6a974636fd36e3391d1de253b (diff)
downloadzig-1f34c03ac14ac352ec03267ca8592dadfbd5e4bc.tar.gz
zig-1f34c03ac14ac352ec03267ca8592dadfbd5e4bc.zip
Merge remote-tracking branch 'origin/master' into llvm12
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig72
1 files changed, 70 insertions, 2 deletions
diff --git a/src/type.zig b/src/type.zig
index 30605ce67b..ecdf0d333a 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -97,6 +97,8 @@ pub const Type = extern union {
.@"struct", .empty_struct => return .Struct,
.@"enum" => return .Enum,
.@"union" => return .Union,
+
+ .var_args_param => unreachable, // can be any type
}
}
@@ -258,6 +260,8 @@ pub const Type = extern union {
if (!a.fnParamType(i).eql(b.fnParamType(i)))
return false;
}
+ if (a.fnIsVarArgs() != b.fnIsVarArgs())
+ return false;
return true;
},
.Optional => {
@@ -323,6 +327,7 @@ pub const Type = extern union {
while (i < params_len) : (i += 1) {
std.hash.autoHash(&hasher, self.fnParamType(i).hash());
}
+ std.hash.autoHash(&hasher, self.fnIsVarArgs());
},
.Optional => {
var buf: Payload.ElemType = undefined;
@@ -397,6 +402,7 @@ pub const Type = extern union {
.@"anyframe",
.inferred_alloc_const,
.inferred_alloc_mut,
+ .var_args_param,
=> unreachable,
.array_u8,
@@ -446,6 +452,7 @@ pub const Type = extern union {
.return_type = try payload.return_type.copy(allocator),
.param_types = param_types,
.cc = payload.cc,
+ .is_var_args = payload.is_var_args,
});
},
.pointer => {
@@ -535,6 +542,7 @@ pub const Type = extern union {
.comptime_int,
.comptime_float,
.noreturn,
+ .var_args_param,
=> return out_stream.writeAll(@tagName(t)),
.enum_literal => return out_stream.writeAll("@Type(.EnumLiteral)"),
@@ -558,6 +566,12 @@ pub const Type = extern union {
if (i != 0) try out_stream.writeAll(", ");
try param_type.format("", .{}, out_stream);
}
+ if (payload.is_var_args) {
+ if (payload.param_types.len != 0) {
+ try out_stream.writeAll(", ");
+ }
+ try out_stream.writeAll("...");
+ }
try out_stream.writeAll(") callconv(.");
try out_stream.writeAll(@tagName(payload.cc));
try out_stream.writeAll(")");
@@ -844,6 +858,7 @@ pub const Type = extern union {
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
+ .var_args_param => unreachable,
};
}
@@ -969,6 +984,7 @@ pub const Type = extern union {
.inferred_alloc_const,
.inferred_alloc_mut,
.@"opaque",
+ .var_args_param,
=> unreachable,
};
}
@@ -995,6 +1011,7 @@ pub const Type = extern union {
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
.@"opaque" => unreachable,
+ .var_args_param => unreachable,
.u8,
.i8,
@@ -1179,6 +1196,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.single_const_pointer,
@@ -1256,6 +1274,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
.const_slice,
@@ -1354,6 +1373,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.const_slice,
@@ -1434,6 +1454,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.single_const_pointer,
@@ -1523,6 +1544,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.pointer => {
@@ -1607,6 +1629,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.pointer => {
@@ -1663,8 +1686,8 @@ pub const Type = extern union {
return ty.optionalChild(&buf).isValidVarType(is_extern);
},
.Pointer, .Array => ty = ty.elemType(),
+ .ErrorUnion => ty = ty.errorUnionChild(),
- .ErrorUnion => @panic("TODO fn isValidVarType"),
.Fn => @panic("TODO fn isValidVarType"),
.Struct => @panic("TODO struct isValidVarType"),
.Union => @panic("TODO union isValidVarType"),
@@ -1733,6 +1756,7 @@ pub const Type = extern union {
.@"struct" => unreachable,
.@"union" => unreachable,
.@"opaque" => unreachable,
+ .var_args_param => unreachable,
.array => self.castTag(.array).?.data.elem_type,
.array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,
@@ -1789,6 +1813,29 @@ pub const Type = extern union {
}
}
+ /// Asserts that the type is an error union.
+ pub fn errorUnionChild(self: Type) Type {
+ return switch (self.tag()) {
+ .anyerror_void_error_union => Type.initTag(.anyerror),
+ .error_union => {
+ const payload = self.castTag(.error_union).?;
+ return payload.data.payload;
+ },
+ else => unreachable,
+ };
+ }
+
+ pub fn errorUnionSet(self: Type) Type {
+ return switch (self.tag()) {
+ .anyerror_void_error_union => Type.initTag(.anyerror),
+ .error_union => {
+ const payload = self.castTag(.error_union).?;
+ return payload.data.error_set;
+ },
+ else => unreachable,
+ };
+ }
+
/// Asserts the type is an array or vector.
pub fn arrayLen(self: Type) u64 {
return switch (self.tag()) {
@@ -1862,6 +1909,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
.array => self.castTag(.array).?.data.len,
@@ -1936,6 +1984,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
.single_const_pointer,
@@ -2025,6 +2074,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.int_signed,
@@ -2110,6 +2160,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.int_unsigned,
@@ -2181,6 +2232,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
.int_unsigned => .{
@@ -2280,6 +2332,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
.usize,
@@ -2400,6 +2453,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
};
}
@@ -2486,6 +2540,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
}
}
@@ -2571,6 +2626,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
}
}
@@ -2656,6 +2712,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
};
}
@@ -2738,6 +2795,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
};
}
@@ -2749,7 +2807,7 @@ pub const Type = extern union {
.fn_void_no_args => false,
.fn_naked_noreturn_no_args => false,
.fn_ccc_void_no_args => false,
- .function => false,
+ .function => self.castTag(.function).?.data.is_var_args,
.f16,
.f32,
@@ -2820,6 +2878,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> unreachable,
};
}
@@ -2902,6 +2961,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> false,
};
}
@@ -2962,6 +3022,7 @@ pub const Type = extern union {
.error_set,
.error_set_single,
.@"opaque",
+ .var_args_param,
=> return null,
.@"enum" => @panic("TODO onePossibleValue enum"),
@@ -3079,6 +3140,7 @@ pub const Type = extern union {
.@"struct",
.@"union",
.@"opaque",
+ .var_args_param,
=> return false,
.c_const_pointer,
@@ -3168,6 +3230,7 @@ pub const Type = extern union {
.pointer,
.inferred_alloc_const,
.inferred_alloc_mut,
+ .var_args_param,
=> unreachable,
.empty_struct => self.castTag(.empty_struct).?.data,
@@ -3285,6 +3348,9 @@ pub const Type = extern union {
anyerror_void_error_union,
@"anyframe",
const_slice_u8,
+ /// This is a special type for variadic parameters of a function call.
+ /// Casts to it will validate that the type can be passed to a c calling convetion function.
+ var_args_param,
/// 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.
@@ -3373,6 +3439,7 @@ pub const Type = extern union {
.const_slice_u8,
.inferred_alloc_const,
.inferred_alloc_mut,
+ .var_args_param,
=> @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
.array_u8,
@@ -3479,6 +3546,7 @@ pub const Type = extern union {
param_types: []Type,
return_type: Type,
cc: std.builtin.CallingConvention,
+ is_var_args: bool,
},
};