union Attribute [src]

Fields

zeroext
signext
inreg
byval: Type
byref: Type
preallocated: Type
inalloca: Type
sret: Type
elementtype: Type
@"align": Alignment
@"noalias"
nocapture
nofree
nest
returned
nonnull
dereferenceable: u32
dereferenceable_or_null: u32
swiftself
swiftasync
swifterror
immarg
noundef
nofpclass: FpClass
alignstack: Alignment
allocalign
allocptr
readnone
readonly
writeonly
allockind: AllocKind
allocsize: AllocSize
alwaysinline
builtin
cold
convergent
disable_sanitizer_information
fn_ret_thunk_extern
hot
inlinehint
jumptable
memory: Memory
minsize
naked
nobuiltin
nocallback
noduplicate
noimplicitfloat
@"noinline"
nomerge
nonlazybind
noprofile
skipprofile
noredzone
noreturn
norecurse
willreturn
nosync
nounwind
nosanitize_bounds
nosanitize_coverage
null_pointer_is_valid
optforfuzzing
optnone
optsize
returns_twice
safestack
sanitize_address
sanitize_memory
sanitize_thread
sanitize_hwaddress
sanitize_memtag
speculative_load_hardening
speculatable
ssp
sspstrong
sspreq
strictfp
uwtable: UwTable
nocf_check
shadowcallstack
mustprogress
vscale_range: VScaleRange
no_sanitize_address
no_sanitize_hwaddress
sanitize_address_dyninit
string: struct { kind: String, value: String }
none: noreturn

Members

Source

pub const Attribute = union(Kind) { // Parameter Attributes zeroext, signext, inreg, byval: Type, byref: Type, preallocated: Type, inalloca: Type, sret: Type, elementtype: Type, @"align": Alignment, @"noalias", nocapture, nofree, nest, returned, nonnull, dereferenceable: u32, dereferenceable_or_null: u32, swiftself, swiftasync, swifterror, immarg, noundef, nofpclass: FpClass, alignstack: Alignment, allocalign, allocptr, readnone, readonly, writeonly, // Function Attributes //alignstack: Alignment, allockind: AllocKind, allocsize: AllocSize, alwaysinline, builtin, cold, convergent, disable_sanitizer_information, fn_ret_thunk_extern, hot, inlinehint, jumptable, memory: Memory, minsize, naked, nobuiltin, nocallback, noduplicate, //nofree, noimplicitfloat, @"noinline", nomerge, nonlazybind, noprofile, skipprofile, noredzone, noreturn, norecurse, willreturn, nosync, nounwind, nosanitize_bounds, nosanitize_coverage, null_pointer_is_valid, optforfuzzing, optnone, optsize, //preallocated: Type, returns_twice, safestack, sanitize_address, sanitize_memory, sanitize_thread, sanitize_hwaddress, sanitize_memtag, speculative_load_hardening, speculatable, ssp, sspstrong, sspreq, strictfp, uwtable: UwTable, nocf_check, shadowcallstack, mustprogress, vscale_range: VScaleRange, // Global Attributes no_sanitize_address, no_sanitize_hwaddress, //sanitize_memtag, sanitize_address_dyninit, string: struct { kind: String, value: String }, none: noreturn, pub const Index = enum(u32) { _, pub fn getKind(self: Index, builder: *const Builder) Kind { return self.toStorage(builder).kind; } pub fn toAttribute(self: Index, builder: *const Builder) Attribute { @setEvalBranchQuota(2_000); const storage = self.toStorage(builder); if (storage.kind.toString()) |kind| return .{ .string = .{ .kind = kind, .value = @enumFromInt(storage.value), } } else return switch (storage.kind) { inline .zeroext, .signext, .inreg, .byval, .byref, .preallocated, .inalloca, .sret, .elementtype, .@"align", .@"noalias", .nocapture, .nofree, .nest, .returned, .nonnull, .dereferenceable, .dereferenceable_or_null, .swiftself, .swiftasync, .swifterror, .immarg, .noundef, .nofpclass, .alignstack, .allocalign, .allocptr, .readnone, .readonly, .writeonly, //.alignstack, .allockind, .allocsize, .alwaysinline, .builtin, .cold, .convergent, .disable_sanitizer_information, .fn_ret_thunk_extern, .hot, .inlinehint, .jumptable, .memory, .minsize, .naked, .nobuiltin, .nocallback, .noduplicate, //.nofree, .noimplicitfloat, .@"noinline", .nomerge, .nonlazybind, .noprofile, .skipprofile, .noredzone, .noreturn, .norecurse, .willreturn, .nosync, .nounwind, .nosanitize_bounds, .nosanitize_coverage, .null_pointer_is_valid, .optforfuzzing, .optnone, .optsize, //.preallocated, .returns_twice, .safestack, .sanitize_address, .sanitize_memory, .sanitize_thread, .sanitize_hwaddress, .sanitize_memtag, .speculative_load_hardening, .speculatable, .ssp, .sspstrong, .sspreq, .strictfp, .uwtable, .nocf_check, .shadowcallstack, .mustprogress, .vscale_range, .no_sanitize_address, .no_sanitize_hwaddress, .sanitize_address_dyninit, => |kind| { const field = comptime blk: { @setEvalBranchQuota(10_000); for (@typeInfo(Attribute).@"union".fields) |field| { if (std.mem.eql(u8, field.name, @tagName(kind))) break :blk field; } unreachable; }; comptime assert(std.mem.eql(u8, @tagName(kind), field.name)); return @unionInit(Attribute, field.name, switch (field.type) { void => {}, u32 => storage.value, Alignment, String, Type, UwTable => @enumFromInt(storage.value), AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value), else => @compileError("bad payload type: " ++ field.name ++ ": " ++ @typeName(field.type)), }); }, .string, .none => unreachable, _ => unreachable, }; } const FormatData = struct { attribute_index: Index, builder: *const Builder, }; fn format( data: FormatData, comptime fmt_str: []const u8, _: std.fmt.FormatOptions, writer: anytype, ) @TypeOf(writer).Error!void { if (comptime std.mem.indexOfNone(u8, fmt_str, "\"#")) |_| @compileError("invalid format string: '" ++ fmt_str ++ "'"); const attribute = data.attribute_index.toAttribute(data.builder); switch (attribute) { .zeroext, .signext, .inreg, .@"noalias", .nocapture, .nofree, .nest, .returned, .nonnull, .swiftself, .swiftasync, .swifterror, .immarg, .noundef, .allocalign, .allocptr, .readnone, .readonly, .writeonly, .alwaysinline, .builtin, .cold, .convergent, .disable_sanitizer_information, .fn_ret_thunk_extern, .hot, .inlinehint, .jumptable, .minsize, .naked, .nobuiltin, .nocallback, .noduplicate, .noimplicitfloat, .@"noinline", .nomerge, .nonlazybind, .noprofile, .skipprofile, .noredzone, .noreturn, .norecurse, .willreturn, .nosync, .nounwind, .nosanitize_bounds, .nosanitize_coverage, .null_pointer_is_valid, .optforfuzzing, .optnone, .optsize, .returns_twice, .safestack, .sanitize_address, .sanitize_memory, .sanitize_thread, .sanitize_hwaddress, .sanitize_memtag, .speculative_load_hardening, .speculatable, .ssp, .sspstrong, .sspreq, .strictfp, .nocf_check, .shadowcallstack, .mustprogress, .no_sanitize_address, .no_sanitize_hwaddress, .sanitize_address_dyninit, => try writer.print(" {s}", .{@tagName(attribute)}), .byval, .byref, .preallocated, .inalloca, .sret, .elementtype, => |ty| try writer.print(" {s}({%})", .{ @tagName(attribute), ty.fmt(data.builder) }), .@"align" => |alignment| try writer.print("{ }", .{alignment}), .dereferenceable, .dereferenceable_or_null, => |size| try writer.print(" {s}({d})", .{ @tagName(attribute), size }), .nofpclass => |fpclass| { const Int = @typeInfo(FpClass).@"struct".backing_integer.?; try writer.print(" {s}(", .{@tagName(attribute)}); var any = false; var remaining: Int = @bitCast(fpclass); inline for (@typeInfo(FpClass).@"struct".decls) |decl| { const pattern: Int = @bitCast(@field(FpClass, decl.name)); if (remaining & pattern == pattern) { if (!any) { try writer.writeByte(' '); any = true; } try writer.writeAll(decl.name); remaining &= ~pattern; } } try writer.writeByte(')'); }, .alignstack => |alignment| try writer.print( if (comptime std.mem.indexOfScalar(u8, fmt_str, '#') != null) " {s}={d}" else " {s}({d})", .{ @tagName(attribute), alignment.toByteUnits() orelse return }, ), .allockind => |allockind| { try writer.print(" {s}(\"", .{@tagName(attribute)}); var any = false; inline for (@typeInfo(AllocKind).@"struct".fields) |field| { if (comptime std.mem.eql(u8, field.name, "_")) continue; if (@field(allockind, field.name)) { if (!any) { try writer.writeByte(','); any = true; } try writer.writeAll(field.name); } } try writer.writeAll("\")"); }, .allocsize => |allocsize| { try writer.print(" {s}({d}", .{ @tagName(attribute), allocsize.elem_size }); if (allocsize.num_elems != AllocSize.none) try writer.print(",{d}", .{allocsize.num_elems}); try writer.writeByte(')'); }, .memory => |memory| { try writer.print(" {s}(", .{@tagName(attribute)}); var any = memory.other != .none or (memory.argmem == .none and memory.inaccessiblemem == .none); if (any) try writer.writeAll(@tagName(memory.other)); inline for (.{ "argmem", "inaccessiblemem" }) |kind| { if (@field(memory, kind) != memory.other) { if (any) try writer.writeAll(", "); try writer.print("{s}: {s}", .{ kind, @tagName(@field(memory, kind)) }); any = true; } } try writer.writeByte(')'); }, .uwtable => |uwtable| if (uwtable != .none) { try writer.print(" {s}", .{@tagName(attribute)}); if (uwtable != UwTable.default) try writer.print("({s})", .{@tagName(uwtable)}); }, .vscale_range => |vscale_range| try writer.print(" {s}({d},{d})", .{ @tagName(attribute), vscale_range.min.toByteUnits().?, vscale_range.max.toByteUnits() orelse 0, }), .string => |string_attr| if (comptime std.mem.indexOfScalar(u8, fmt_str, '"') != null) { try writer.print(" {\"}", .{string_attr.kind.fmt(data.builder)}); if (string_attr.value != .empty) try writer.print("={\"}", .{string_attr.value.fmt(data.builder)}); }, .none => unreachable, } } pub fn fmt(self: Index, builder: *const Builder) std.fmt.Formatter(format) { return .{ .data = .{ .attribute_index = self, .builder = builder } }; } fn toStorage(self: Index, builder: *const Builder) Storage { return builder.attributes.keys()[@intFromEnum(self)]; } }; pub const Kind = enum(u32) { // Parameter Attributes zeroext = 34, signext = 24, inreg = 5, byval = 3, byref = 69, preallocated = 65, inalloca = 38, sret = 29, // TODO: ? elementtype = 77, @"align" = 1, @"noalias" = 9, nocapture = 11, nofree = 62, nest = 8, returned = 22, nonnull = 39, dereferenceable = 41, dereferenceable_or_null = 42, swiftself = 46, swiftasync = 75, swifterror = 47, immarg = 60, noundef = 68, nofpclass = 87, alignstack = 25, allocalign = 80, allocptr = 81, readnone = 20, readonly = 21, writeonly = 52, // Function Attributes //alignstack, allockind = 82, allocsize = 51, alwaysinline = 2, builtin = 35, cold = 36, convergent = 43, disable_sanitizer_information = 78, fn_ret_thunk_extern = 84, hot = 72, inlinehint = 4, jumptable = 40, memory = 86, minsize = 6, naked = 7, nobuiltin = 10, nocallback = 71, noduplicate = 12, //nofree, noimplicitfloat = 13, @"noinline" = 14, nomerge = 66, nonlazybind = 15, noprofile = 73, skipprofile = 85, noredzone = 16, noreturn = 17, norecurse = 48, willreturn = 61, nosync = 63, nounwind = 18, nosanitize_bounds = 79, nosanitize_coverage = 76, null_pointer_is_valid = 67, optforfuzzing = 57, optnone = 37, optsize = 19, //preallocated, returns_twice = 23, safestack = 44, sanitize_address = 30, sanitize_memory = 32, sanitize_thread = 31, sanitize_hwaddress = 55, sanitize_memtag = 64, speculative_load_hardening = 59, speculatable = 53, ssp = 26, sspstrong = 28, sspreq = 27, strictfp = 54, uwtable = 33, nocf_check = 56, shadowcallstack = 58, mustprogress = 70, vscale_range = 74, // Global Attributes no_sanitize_address = 100, no_sanitize_hwaddress = 101, //sanitize_memtag, sanitize_address_dyninit = 102, string = std.math.maxInt(u31), none = std.math.maxInt(u32), _, pub const len = @typeInfo(Kind).@"enum".fields.len - 2; pub fn fromString(str: String) Kind { assert(!str.isAnon()); const kind: Kind = @enumFromInt(@intFromEnum(str)); assert(kind != .none); return kind; } fn toString(self: Kind) ?String { assert(self != .none); const str: String = @enumFromInt(@intFromEnum(self)); return if (str.isAnon()) null else str; } }; pub const FpClass = packed struct(u32) { signaling_nan: bool = false, quiet_nan: bool = false, negative_infinity: bool = false, negative_normal: bool = false, negative_subnormal: bool = false, negative_zero: bool = false, positive_zero: bool = false, positive_subnormal: bool = false, positive_normal: bool = false, positive_infinity: bool = false, _: u22 = 0, pub const all = FpClass{ .signaling_nan = true, .quiet_nan = true, .negative_infinity = true, .negative_normal = true, .negative_subnormal = true, .negative_zero = true, .positive_zero = true, .positive_subnormal = true, .positive_normal = true, .positive_infinity = true, }; pub const nan = FpClass{ .signaling_nan = true, .quiet_nan = true }; pub const snan = FpClass{ .signaling_nan = true }; pub const qnan = FpClass{ .quiet_nan = true }; pub const inf = FpClass{ .negative_infinity = true, .positive_infinity = true }; pub const ninf = FpClass{ .negative_infinity = true }; pub const pinf = FpClass{ .positive_infinity = true }; pub const zero = FpClass{ .positive_zero = true, .negative_zero = true }; pub const nzero = FpClass{ .negative_zero = true }; pub const pzero = FpClass{ .positive_zero = true }; pub const sub = FpClass{ .positive_subnormal = true, .negative_subnormal = true }; pub const nsub = FpClass{ .negative_subnormal = true }; pub const psub = FpClass{ .positive_subnormal = true }; pub const norm = FpClass{ .positive_normal = true, .negative_normal = true }; pub const nnorm = FpClass{ .negative_normal = true }; pub const pnorm = FpClass{ .positive_normal = true }; }; pub const AllocKind = packed struct(u32) { alloc: bool, realloc: bool, free: bool, uninitialized: bool, zeroed: bool, aligned: bool, _: u26 = 0, }; pub const AllocSize = packed struct(u32) { elem_size: u16, num_elems: u16, pub const none = std.math.maxInt(u16); fn toLlvm(self: AllocSize) packed struct(u64) { num_elems: u32, elem_size: u32 } { return .{ .num_elems = switch (self.num_elems) { else => self.num_elems, none => std.math.maxInt(u32), }, .elem_size = self.elem_size }; } }; pub const Memory = packed struct(u32) { argmem: Effect = .none, inaccessiblemem: Effect = .none, other: Effect = .none, _: u26 = 0, pub const Effect = enum(u2) { none, read, write, readwrite }; fn all(effect: Effect) Memory { return .{ .argmem = effect, .inaccessiblemem = effect, .other = effect }; } }; pub const UwTable = enum(u32) { none, sync, @"async", pub const default = UwTable.@"async"; }; pub const VScaleRange = packed struct(u32) { min: Alignment, max: Alignment, _: u20 = 0, fn toLlvm(self: VScaleRange) packed struct(u64) { max: u32, min: u32 } { return .{ .max = @intCast(self.max.toByteUnits() orelse 0), .min = @intCast(self.min.toByteUnits().?), }; } }; pub fn getKind(self: Attribute) Kind { return switch (self) { else => self, .string => |string_attr| Kind.fromString(string_attr.kind), }; } const Storage = extern struct { kind: Kind, value: u32, }; fn toStorage(self: Attribute) Storage { return switch (self) { inline else => |value, tag| .{ .kind = @as(Kind, self), .value = switch (@TypeOf(value)) { void => 0, u32 => value, Alignment, String, Type, UwTable => @intFromEnum(value), AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(value), else => @compileError("bad payload type: " ++ @tagName(tag) ++ @typeName(@TypeOf(value))), } }, .string => |string_attr| .{ .kind = Kind.fromString(string_attr.kind), .value = @intFromEnum(string_attr.value), }, .none => unreachable, }; } }