enum Index [src]
Fields
_
Members
- fmt (Function)
- getKind (Function)
- toAttribute (Function)
Source
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)];
}
}