Commit 5792570197
Changed files (49)
deps
aro
codegen
object
toolchains
deps/aro/builtins/BuiltinFunction.zig
@@ -0,0 +1,35783 @@
+//! Autogenerated by process_builtins.py, do not edit
+
+const std = @import("std");
+const Properties = @import("Properties.zig");
+const TypeDescription = @import("TypeDescription.zig");
+const Attributes = Properties.Attributes;
+const TargetSet = Properties.TargetSet;
+
+pub const Tag = blk: {
+ @setEvalBranchQuota(10000);
+ break :blk std.meta.DeclEnum(functions);
+};
+
+tag: Tag,
+param_str: []const u8,
+properties: Properties,
+
+pub fn fromTag(builtin: Tag) @This() {
+ @setEvalBranchQuota(10000);
+ switch (builtin) {
+ inline else => |tag| {
+ const desc = @field(functions, @tagName(tag));
+ return .{
+ .tag = tag,
+ .param_str = desc.param_str,
+ .properties = .{
+ .language = if (@hasDecl(desc, "language")) @field(desc, "language") else .all_languages,
+ .header = if (@hasDecl(desc, "header")) @field(desc, "header") else .none,
+ .attributes = if (@hasDecl(desc, "attributes")) @field(desc, "attributes") else Attributes{},
+ .target_set = if (@hasDecl(desc, "target_set")) @field(desc, "target_set") else TargetSet.init(.{ .basic = true }),
+ },
+ };
+ },
+ }
+}
+
+pub fn isVarArgs(self: @This()) bool {
+ return self.param_str[self.param_str.len - 1] == '.';
+}
+
+const functions = struct {
+ pub const _Block_object_assign = struct {
+ const param_str = "vv*vC*iC";
+ const header = .blocks;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _Block_object_dispose = struct {
+ const param_str = "vvC*iC";
+ const header = .blocks;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _Exit = struct {
+ const param_str = "vi";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .noreturn = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _InterlockedAnd = struct {
+ const param_str = "NiNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedAnd16 = struct {
+ const param_str = "ssD*s";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedAnd8 = struct {
+ const param_str = "ccD*c";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedCompareExchange = struct {
+ const param_str = "NiNiD*NiNi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedCompareExchange16 = struct {
+ const param_str = "ssD*ss";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedCompareExchange64 = struct {
+ const param_str = "LLiLLiD*LLiLLi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedCompareExchange8 = struct {
+ const param_str = "ccD*cc";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedCompareExchangePointer = struct {
+ const param_str = "v*v*D*v*v*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedCompareExchangePointer_nf = struct {
+ const param_str = "v*v*D*v*v*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedDecrement = struct {
+ const param_str = "NiNiD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedDecrement16 = struct {
+ const param_str = "ssD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchange = struct {
+ const param_str = "NiNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchange16 = struct {
+ const param_str = "ssD*s";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchange8 = struct {
+ const param_str = "ccD*c";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchangeAdd = struct {
+ const param_str = "NiNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchangeAdd16 = struct {
+ const param_str = "ssD*s";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchangeAdd8 = struct {
+ const param_str = "ccD*c";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchangePointer = struct {
+ const param_str = "v*v*D*v*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchangeSub = struct {
+ const param_str = "NiNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchangeSub16 = struct {
+ const param_str = "ssD*s";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedExchangeSub8 = struct {
+ const param_str = "ccD*c";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedIncrement = struct {
+ const param_str = "NiNiD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedIncrement16 = struct {
+ const param_str = "ssD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedOr = struct {
+ const param_str = "NiNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedOr16 = struct {
+ const param_str = "ssD*s";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedOr8 = struct {
+ const param_str = "ccD*c";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedXor = struct {
+ const param_str = "NiNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedXor16 = struct {
+ const param_str = "ssD*s";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _InterlockedXor8 = struct {
+ const param_str = "ccD*c";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _MoveFromCoprocessor = struct {
+ const param_str = "UiIUiIUiIUiIUiIUi";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const _MoveFromCoprocessor2 = struct {
+ const param_str = "UiIUiIUiIUiIUiIUi";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const _MoveToCoprocessor = struct {
+ const param_str = "vUiIUiIUiIUiIUiIUi";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const _MoveToCoprocessor2 = struct {
+ const param_str = "vUiIUiIUiIUiIUiIUi";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const _ReturnAddress = struct {
+ const param_str = "v*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __GetExceptionInfo = struct {
+ const param_str = "v*.";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .eval_args = false,
+ };
+ };
+
+ pub const __abnormal_termination = struct {
+ const param_str = "i";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __annotation = struct {
+ const param_str = "wC*.";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __arithmetic_fence = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __assume = struct {
+ const param_str = "vb";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __atomic_always_lock_free = struct {
+ const param_str = "bzvCD*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __atomic_clear = struct {
+ const param_str = "vvD*i";
+ const attributes = Attributes{};
+ };
+
+ pub const __atomic_is_lock_free = struct {
+ const param_str = "bzvCD*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __atomic_signal_fence = struct {
+ const param_str = "vi";
+ const attributes = Attributes{};
+ };
+
+ pub const __atomic_test_and_set = struct {
+ const param_str = "bvD*i";
+ const attributes = Attributes{};
+ };
+
+ pub const __atomic_thread_fence = struct {
+ const param_str = "vi";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin___CFStringMakeConstantString = struct {
+ const param_str = "FC*cC*";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin___NSStringMakeConstantString = struct {
+ const param_str = "FC*cC*";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin___clear_cache = struct {
+ const param_str = "vc*c*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin___fprintf_chk = struct {
+ const param_str = "iP*icC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 2,
+ };
+ };
+
+ pub const __builtin___get_unsafe_stack_bottom = struct {
+ const param_str = "v*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___get_unsafe_stack_ptr = struct {
+ const param_str = "v*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___get_unsafe_stack_start = struct {
+ const param_str = "v*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___get_unsafe_stack_top = struct {
+ const param_str = "v*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___memccpy_chk = struct {
+ const param_str = "v*v*vC*izz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___memcpy_chk = struct {
+ const param_str = "v*v*vC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___memmove_chk = struct {
+ const param_str = "v*v*vC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___mempcpy_chk = struct {
+ const param_str = "v*v*vC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___memset_chk = struct {
+ const param_str = "v*v*izz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___printf_chk = struct {
+ const param_str = "iicC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const __builtin___snprintf_chk = struct {
+ const param_str = "ic*zizcC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 4,
+ };
+ };
+
+ pub const __builtin___sprintf_chk = struct {
+ const param_str = "ic*izcC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 3,
+ };
+ };
+
+ pub const __builtin___stpcpy_chk = struct {
+ const param_str = "c*c*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___stpncpy_chk = struct {
+ const param_str = "c*c*cC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___strcat_chk = struct {
+ const param_str = "c*c*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___strcpy_chk = struct {
+ const param_str = "c*c*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___strlcat_chk = struct {
+ const param_str = "zc*cC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___strlcpy_chk = struct {
+ const param_str = "zc*cC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___strncat_chk = struct {
+ const param_str = "c*c*cC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___strncpy_chk = struct {
+ const param_str = "c*c*cC*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin___vfprintf_chk = struct {
+ const param_str = "iP*icC*a";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 2,
+ };
+ };
+
+ pub const __builtin___vprintf_chk = struct {
+ const param_str = "iicC*a";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const __builtin___vsnprintf_chk = struct {
+ const param_str = "ic*zizcC*a";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 4,
+ };
+ };
+
+ pub const __builtin___vsprintf_chk = struct {
+ const param_str = "ic*izcC*a";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 3,
+ };
+ };
+
+ pub const __builtin_abort = struct {
+ const param_str = "v";
+ const attributes = Attributes{
+ .noreturn = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_abs = struct {
+ const param_str = "ii";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_acos = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_acosf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_acosf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_acosh = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_acoshf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_acoshf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_acoshl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_acosl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_add_overflow = struct {
+ const param_str = "b.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_addc = struct {
+ const param_str = "UiUiCUiCUiCUi*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_addcb = struct {
+ const param_str = "UcUcCUcCUcCUc*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_addcl = struct {
+ const param_str = "ULiULiCULiCULiCULi*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_addcll = struct {
+ const param_str = "ULLiULLiCULLiCULLiCULLi*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_addcs = struct {
+ const param_str = "UsUsCUsCUsCUs*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_addf128_round_to_odd = struct {
+ const param_str = "LLdLLdLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_align_down = struct {
+ const param_str = "v*vC*z";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_align_up = struct {
+ const param_str = "v*vC*z";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_alloca = struct {
+ const param_str = "v*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_alloca_uninitialized = struct {
+ const param_str = "v*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_alloca_with_align = struct {
+ const param_str = "v*zIz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_alloca_with_align_uninitialized = struct {
+ const param_str = "v*zIz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_altivec_crypto_vcipher = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vcipherlast = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vncipher = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vncipherlast = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vpermxor = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vpermxor_be = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vpmsumb = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vpmsumd = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vpmsumh = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vpmsumw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vsbox = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vshasigmad = struct {
+ const param_str = "V2ULLiV2ULLiIiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_crypto_vshasigmaw = struct {
+ const param_str = "V4UiV4UiIiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_dss = struct {
+ const param_str = "vUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_dssall = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_dst = struct {
+ const param_str = "vvC*iUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_dstst = struct {
+ const param_str = "vvC*iUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_dststt = struct {
+ const param_str = "vvC*iUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_dstt = struct {
+ const param_str = "vvC*iUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_lvebx = struct {
+ const param_str = "V16cLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_lvehx = struct {
+ const param_str = "V8sLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_lvewx = struct {
+ const param_str = "V4iLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_lvsl = struct {
+ const param_str = "V16cUcvC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_lvsr = struct {
+ const param_str = "V16cUcvC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_lvx = struct {
+ const param_str = "V4iLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_lvxl = struct {
+ const param_str = "V4iLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_mfvscr = struct {
+ const param_str = "V8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_mtvscr = struct {
+ const param_str = "vV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_mtvsrbm = struct {
+ const param_str = "V16UcULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_mtvsrdm = struct {
+ const param_str = "V2ULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_mtvsrhm = struct {
+ const param_str = "V8UsULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_mtvsrqm = struct {
+ const param_str = "V1ULLLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_mtvsrwm = struct {
+ const param_str = "V4UiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_stvebx = struct {
+ const param_str = "vV16cLiv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_stvehx = struct {
+ const param_str = "vV8sLiv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_stvewx = struct {
+ const param_str = "vV4iLiv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_stvx = struct {
+ const param_str = "vV4iLiv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_stvxl = struct {
+ const param_str = "vV4iLiv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vabsdub = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vabsduh = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vabsduw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddcuq = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddcuq_c = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddcuw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddecuq = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddecuq_c = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddeuqm = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddeuqm_c = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddsbs = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddshs = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddsws = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vaddubs = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vadduhs = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vadduqm = struct {
+ const param_str = "V1ULLLiV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vadduws = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vavgsb = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vavgsh = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vavgsw = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vavgub = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vavguh = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vavguw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vbpermd = struct {
+ const param_str = "V2ULLiV2ULLiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vbpermq = struct {
+ const param_str = "V2ULLiV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcfsx = struct {
+ const param_str = "V4fV4SiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcfuged = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcfux = struct {
+ const param_str = "V4fV4UiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclrlb = struct {
+ const param_str = "V16UcV16UcUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclrrb = struct {
+ const param_str = "V16UcV16UcUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclzb = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclzd = struct {
+ const param_str = "V2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclzdm = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclzh = struct {
+ const param_str = "V8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclzlsbb = struct {
+ const param_str = "SiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vclzw = struct {
+ const param_str = "V4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpbfp = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpbfp_p = struct {
+ const param_str = "iiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpeqfp = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpeqfp_p = struct {
+ const param_str = "iiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequb = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequb_p = struct {
+ const param_str = "iiV16cV16c";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequd = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequd_p = struct {
+ const param_str = "iiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequh = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequh_p = struct {
+ const param_str = "iiV8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequq = struct {
+ const param_str = "V1LLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequq_p = struct {
+ const param_str = "iiV1ULLLiV1LLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequw = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpequw_p = struct {
+ const param_str = "iiV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgefp = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgefp_p = struct {
+ const param_str = "iiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtfp = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtfp_p = struct {
+ const param_str = "iiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsb = struct {
+ const param_str = "V16cV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsb_p = struct {
+ const param_str = "iiV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsd = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsd_p = struct {
+ const param_str = "iiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsh = struct {
+ const param_str = "V8sV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsh_p = struct {
+ const param_str = "iiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsq = struct {
+ const param_str = "V1LLLiV1SLLLiV1SLLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsq_p = struct {
+ const param_str = "iiV1SLLLiV1SLLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsw = struct {
+ const param_str = "V4iV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtsw_p = struct {
+ const param_str = "iiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtub = struct {
+ const param_str = "V16cV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtub_p = struct {
+ const param_str = "iiV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtud = struct {
+ const param_str = "V2LLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtud_p = struct {
+ const param_str = "iiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtuh = struct {
+ const param_str = "V8sV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtuh_p = struct {
+ const param_str = "iiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtuq = struct {
+ const param_str = "V1LLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtuq_p = struct {
+ const param_str = "iiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtuw = struct {
+ const param_str = "V4iV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpgtuw_p = struct {
+ const param_str = "iiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpneb = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpneb_p = struct {
+ const param_str = "iiV16cV16c";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpned_p = struct {
+ const param_str = "iiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpneh = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpneh_p = struct {
+ const param_str = "iiV8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpnew = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpnew_p = struct {
+ const param_str = "iiV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpnezb = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpnezh = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcmpnezw = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcntmbb = struct {
+ const param_str = "ULLiV16UcUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcntmbd = struct {
+ const param_str = "ULLiV2ULLiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcntmbh = struct {
+ const param_str = "ULLiV8UsUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vcntmbw = struct {
+ const param_str = "ULLiV4UiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctsxs = struct {
+ const param_str = "V4SiV4fIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctuxs = struct {
+ const param_str = "V4UiV4fIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctzb = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctzd = struct {
+ const param_str = "V2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctzdm = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctzh = struct {
+ const param_str = "V8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctzlsbb = struct {
+ const param_str = "SiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vctzw = struct {
+ const param_str = "V4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vdivesd = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vdivesq = struct {
+ const param_str = "V1SLLLiV1SLLLiV1SLLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vdivesw = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vdiveud = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vdiveuq = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vdiveuw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vexpandbm = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vexpanddm = struct {
+ const param_str = "V2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vexpandhm = struct {
+ const param_str = "V8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vexpandqm = struct {
+ const param_str = "V1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vexpandwm = struct {
+ const param_str = "V4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vexptefp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextddvlx = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextddvrx = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextdubvlx = struct {
+ const param_str = "V2ULLiV16UcV16UcUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextdubvrx = struct {
+ const param_str = "V2ULLiV16UcV16UcUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextduhvlx = struct {
+ const param_str = "V2ULLiV8UsV8UsUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextduhvrx = struct {
+ const param_str = "V2ULLiV8UsV8UsUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextduwvlx = struct {
+ const param_str = "V2ULLiV4UiV4UiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextduwvrx = struct {
+ const param_str = "V2ULLiV4UiV4UiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextractbm = struct {
+ const param_str = "UiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextractdm = struct {
+ const param_str = "UiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextracthm = struct {
+ const param_str = "UiV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextractqm = struct {
+ const param_str = "UiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextractwm = struct {
+ const param_str = "UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextsb2d = struct {
+ const param_str = "V2SLLiV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextsb2w = struct {
+ const param_str = "V4SiV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextsd2q = struct {
+ const param_str = "V1SLLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextsh2d = struct {
+ const param_str = "V2SLLiV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextsh2w = struct {
+ const param_str = "V4SiV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vextsw2d = struct {
+ const param_str = "V2SLLiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vgbbd = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vgnb = struct {
+ const param_str = "ULLiV1ULLLiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsblx = struct {
+ const param_str = "V16UcV16UcUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsbrx = struct {
+ const param_str = "V16UcV16UcUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsbvlx = struct {
+ const param_str = "V16UcV16UcUiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsbvrx = struct {
+ const param_str = "V16UcV16UcUiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsd = struct {
+ const param_str = "V16UcV16UcULLiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsd_elt = struct {
+ const param_str = "V16UcV16UcULLiiC";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsdlx = struct {
+ const param_str = "V2ULLiV2ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsdrx = struct {
+ const param_str = "V2ULLiV2ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinshlx = struct {
+ const param_str = "V8UsV8UsUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinshrx = struct {
+ const param_str = "V8UsV8UsUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinshvlx = struct {
+ const param_str = "V8UsV8UsUiV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinshvrx = struct {
+ const param_str = "V8UsV8UsUiV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsw = struct {
+ const param_str = "V16UcV16UcUiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinsw_elt = struct {
+ const param_str = "V16UcV16UcUiiC";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinswlx = struct {
+ const param_str = "V4UiV4UiUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinswrx = struct {
+ const param_str = "V4UiV4UiUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinswvlx = struct {
+ const param_str = "V4UiV4UiUiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vinswvrx = struct {
+ const param_str = "V4UiV4UiUiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vlogefp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaddfp = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxfp = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxsb = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxsd = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxsh = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxsw = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxub = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxud = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxuh = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmaxuw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmhaddshs = struct {
+ const param_str = "V8sV8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmhraddshs = struct {
+ const param_str = "V8sV8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminfp = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminsb = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminsd = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminsh = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminsw = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminub = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminud = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminuh = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vminuw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmsumcud = struct {
+ const param_str = "V1ULLLiV2ULLiV2ULLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmsummbm = struct {
+ const param_str = "V4SiV16ScV16UcV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmsumshm = struct {
+ const param_str = "V4SiV8SsV8SsV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmsumshs = struct {
+ const param_str = "V4SiV8SsV8SsV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmsumubm = struct {
+ const param_str = "V4UiV16UcV16UcV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmsumuhm = struct {
+ const param_str = "V4UiV8UsV8UsV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmsumuhs = struct {
+ const param_str = "V4UiV8UsV8UsV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulesb = struct {
+ const param_str = "V8SsV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulesd = struct {
+ const param_str = "V1SLLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulesh = struct {
+ const param_str = "V4SiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulesw = struct {
+ const param_str = "V2SLLiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmuleub = struct {
+ const param_str = "V8UsV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmuleud = struct {
+ const param_str = "V1ULLLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmuleuh = struct {
+ const param_str = "V4UiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmuleuw = struct {
+ const param_str = "V2ULLiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulhsd = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulhsw = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulhud = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulhuw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulosb = struct {
+ const param_str = "V8SsV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulosd = struct {
+ const param_str = "V1SLLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulosh = struct {
+ const param_str = "V4SiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulosw = struct {
+ const param_str = "V2SLLiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmuloub = struct {
+ const param_str = "V8UsV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmuloud = struct {
+ const param_str = "V1ULLLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulouh = struct {
+ const param_str = "V4UiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vmulouw = struct {
+ const param_str = "V2ULLiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vnmsubfp = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpdepd = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vperm_4si = struct {
+ const param_str = "V4iV4iV4iV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpextd = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkpx = struct {
+ const param_str = "V8sV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpksdss = struct {
+ const param_str = "V4SiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpksdus = struct {
+ const param_str = "V4UiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkshss = struct {
+ const param_str = "V16ScV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkshus = struct {
+ const param_str = "V16UcV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkswss = struct {
+ const param_str = "V8SsV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkswus = struct {
+ const param_str = "V8UsV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkudum = struct {
+ const param_str = "V4UiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkudus = struct {
+ const param_str = "V4UiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkuhus = struct {
+ const param_str = "V16UcV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpkuwus = struct {
+ const param_str = "V8UsV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpopcntb = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpopcntd = struct {
+ const param_str = "V2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpopcnth = struct {
+ const param_str = "V8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vpopcntw = struct {
+ const param_str = "V4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vprtybd = struct {
+ const param_str = "V2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vprtybq = struct {
+ const param_str = "V1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vprtybw = struct {
+ const param_str = "V4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrefp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrfim = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrfin = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrfip = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrfiz = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrlb = struct {
+ const param_str = "V16cV16cV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrld = struct {
+ const param_str = "V2LLiV2LLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrldmi = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrldnm = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrlh = struct {
+ const param_str = "V8sV8sV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrlqmi = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrlqnm = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrlw = struct {
+ const param_str = "V4iV4iV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrlwmi = struct {
+ const param_str = "V4UiV4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrlwnm = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vrsqrtefp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsel_4si = struct {
+ const param_str = "V4iV4iV4iV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsl = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsldbi = struct {
+ const param_str = "V16UcV16UcV16UcIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vslo = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vslv = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsr = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsrab = struct {
+ const param_str = "V16cV16cV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsrah = struct {
+ const param_str = "V8sV8sV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsraw = struct {
+ const param_str = "V4iV4iV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsrdbi = struct {
+ const param_str = "V16UcV16UcV16UcIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsro = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsrv = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstribl = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstribl_p = struct {
+ const param_str = "iiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstribr = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstribr_p = struct {
+ const param_str = "iiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstrihl = struct {
+ const param_str = "V8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstrihl_p = struct {
+ const param_str = "iiV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstrihr = struct {
+ const param_str = "V8sV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vstrihr_p = struct {
+ const param_str = "iiV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubcuq = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubcuq_c = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubcuw = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubecuq = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubecuq_c = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubeuqm = struct {
+ const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubeuqm_c = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubsbs = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubshs = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubsws = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsububs = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubuhs = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubuqm = struct {
+ const param_str = "V1ULLLiV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsubuws = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsum2sws = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsum4sbs = struct {
+ const param_str = "V4SiV16ScV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsum4shs = struct {
+ const param_str = "V4SiV8SsV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsum4ubs = struct {
+ const param_str = "V4UiV16UcV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vsumsws = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupkhpx = struct {
+ const param_str = "V4UiV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupkhsb = struct {
+ const param_str = "V8sV16c";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupkhsh = struct {
+ const param_str = "V4iV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupkhsw = struct {
+ const param_str = "V2LLiV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupklpx = struct {
+ const param_str = "V4UiV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupklsb = struct {
+ const param_str = "V8sV16c";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupklsh = struct {
+ const param_str = "V4iV8s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_altivec_vupklsw = struct {
+ const param_str = "V2LLiV4i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_amdgcn_alignbit = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_alignbyte = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_atomic_dec32 = struct {
+ const param_str = "UZiUZiD*UZiUicC*";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_atomic_dec64 = struct {
+ const param_str = "UWiUWiD*UWiUicC*";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_atomic_inc32 = struct {
+ const param_str = "UZiUZiD*UZiUicC*";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_atomic_inc64 = struct {
+ const param_str = "UWiUWiD*UWiUicC*";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_buffer_wbinvl1 = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_class = struct {
+ const param_str = "bdi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_classf = struct {
+ const param_str = "bfi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cosf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cubeid = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cubema = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cubesc = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cubetc = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cvt_pk_i16 = struct {
+ const param_str = "E2sii";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cvt_pk_u16 = struct {
+ const param_str = "E2UsUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cvt_pk_u8_f32 = struct {
+ const param_str = "UifUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cvt_pknorm_i16 = struct {
+ const param_str = "E2sff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cvt_pknorm_u16 = struct {
+ const param_str = "E2Usff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_cvt_pkrtz = struct {
+ const param_str = "E2hff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_dispatch_ptr = struct {
+ const param_str = "v*4";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_div_fixup = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_div_fixupf = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_div_fmas = struct {
+ const param_str = "ddddb";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_div_fmasf = struct {
+ const param_str = "ffffb";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_div_scale = struct {
+ const param_str = "dddbb*";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_div_scalef = struct {
+ const param_str = "fffbb*";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_append = struct {
+ const param_str = "ii*3";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_bpermute = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_ds_consume = struct {
+ const param_str = "ii*3";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_faddf = struct {
+ const param_str = "ff*3fIiIiIb";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_fmaxf = struct {
+ const param_str = "ff*3fIiIiIb";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_fminf = struct {
+ const param_str = "ff*3fIiIiIb";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_gws_barrier = struct {
+ const param_str = "vUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_gws_init = struct {
+ const param_str = "vUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_gws_sema_br = struct {
+ const param_str = "vUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_gws_sema_p = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_gws_sema_v = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_ds_permute = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_ds_swizzle = struct {
+ const param_str = "iiIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_endpgm = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .noreturn = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_fcmp = struct {
+ const param_str = "WUiddIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_fcmpf = struct {
+ const param_str = "WUiffIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_fence = struct {
+ const param_str = "vUicC*";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_fmed3f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_fract = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_fractf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_frexp_exp = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_frexp_expf = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_frexp_mant = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_frexp_mantf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_grid_size_x = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_grid_size_y = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_grid_size_z = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_groupstaticsize = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_iglp_opt = struct {
+ const param_str = "vIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_implicitarg_ptr = struct {
+ const param_str = "v*4";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_interp_mov = struct {
+ const param_str = "fUiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_interp_p1 = struct {
+ const param_str = "ffUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_interp_p1_f16 = struct {
+ const param_str = "ffUiUibUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_interp_p2 = struct {
+ const param_str = "fffUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_interp_p2_f16 = struct {
+ const param_str = "hffUiUibUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_is_private = struct {
+ const param_str = "bvC*0";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_is_shared = struct {
+ const param_str = "bvC*0";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_kernarg_segment_ptr = struct {
+ const param_str = "v*4";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_ldexp = struct {
+ const param_str = "ddi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_ldexpf = struct {
+ const param_str = "ffi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_lerp = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_log_clampf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_mbcnt_hi = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_mbcnt_lo = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_mqsad_pk_u16_u8 = struct {
+ const param_str = "WUiWUiUiWUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_mqsad_u32_u8 = struct {
+ const param_str = "V4UiWUiUiV4Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_msad_u8 = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_qsad_pk_u16_u8 = struct {
+ const param_str = "WUiWUiUiWUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_queue_ptr = struct {
+ const param_str = "v*4";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_rcp = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_rcpf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_read_exec = struct {
+ const param_str = "WUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_read_exec_hi = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_read_exec_lo = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_readfirstlane = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_readlane = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_rsq = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_rsq_clamp = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_rsq_clampf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_rsqf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_s_barrier = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_dcache_inv = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_decperflevel = struct {
+ const param_str = "vIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_getpc = struct {
+ const param_str = "WUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_getreg = struct {
+ const param_str = "UiIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_incperflevel = struct {
+ const param_str = "vIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_sendmsg = struct {
+ const param_str = "vIiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_sendmsghalt = struct {
+ const param_str = "vIiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_setprio = struct {
+ const param_str = "vIs";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_setreg = struct {
+ const param_str = "vIiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_sleep = struct {
+ const param_str = "vIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_s_waitcnt = struct {
+ const param_str = "vIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_sad_hi_u8 = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sad_u16 = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sad_u8 = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sbfe = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sched_barrier = struct {
+ const param_str = "vIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_sched_group_barrier = struct {
+ const param_str = "vIiIiIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_sicmp = struct {
+ const param_str = "WUiiiIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sicmpl = struct {
+ const param_str = "WUiWiWiIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sinf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sqrt = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_sqrtf = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_trig_preop = struct {
+ const param_str = "ddi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_trig_preopf = struct {
+ const param_str = "ffi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_ubfe = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_uicmp = struct {
+ const param_str = "WUiUiUiIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_uicmpl = struct {
+ const param_str = "WUiWUiWUiIi";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_wave_barrier = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_amdgcn_workgroup_id_x = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workgroup_id_y = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workgroup_id_z = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workgroup_size_x = struct {
+ const param_str = "Us";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workgroup_size_y = struct {
+ const param_str = "Us";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workgroup_size_z = struct {
+ const param_str = "Us";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workitem_id_x = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workitem_id_y = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_amdgcn_workitem_id_z = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_annotation = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_arm_cdp = struct {
+ const param_str = "vUIiUIiUIiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_cdp2 = struct {
+ const param_str = "vUIiUIiUIiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_clrex = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_cls = struct {
+ const param_str = "UiZUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_cls64 = struct {
+ const param_str = "UiWUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_cmse_TT = struct {
+ const param_str = "Uiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_arm_cmse_TTA = struct {
+ const param_str = "Uiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_arm_cmse_TTAT = struct {
+ const param_str = "Uiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_arm_cmse_TTT = struct {
+ const param_str = "Uiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_arm_dbg = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_dmb = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_dsb = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_get_fpscr = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_isb = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_ldaex = struct {
+ const param_str = "v.";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_arm_ldc = struct {
+ const param_str = "vUIiUIivC*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_ldc2 = struct {
+ const param_str = "vUIiUIivC*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_ldc2l = struct {
+ const param_str = "vUIiUIivC*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_ldcl = struct {
+ const param_str = "vUIiUIivC*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_ldrex = struct {
+ const param_str = "v.";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_arm_ldrexd = struct {
+ const param_str = "LLUiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mcr = struct {
+ const param_str = "vUIiUIiUiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mcr2 = struct {
+ const param_str = "vUIiUIiUiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mcrr = struct {
+ const param_str = "vUIiUIiLLUiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mcrr2 = struct {
+ const param_str = "vUIiUIiLLUiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mrc = struct {
+ const param_str = "UiUIiUIiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mrc2 = struct {
+ const param_str = "UiUIiUIiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mrrc = struct {
+ const param_str = "LLUiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_mrrc2 = struct {
+ const param_str = "LLUiUIiUIiUIi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_nop = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_prefetch = struct {
+ const param_str = "!";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qadd = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qadd16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qadd8 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qasx = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qdbl = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qsax = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qsub = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qsub16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_qsub8 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_rbit = struct {
+ const param_str = "UiUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_rbit64 = struct {
+ const param_str = "WUiWUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_rsr = struct {
+ const param_str = "UicC*";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_rsr128 = struct {
+ const param_str = "LLLUicC*";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_rsr64 = struct {
+ const param_str = "!";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_rsrp = struct {
+ const param_str = "v*cC*";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_sadd16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_sadd8 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_sasx = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_sel = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_set_fpscr = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_sev = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_sevl = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_shadd16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_shadd8 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_shasx = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_shsax = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_shsub16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_shsub8 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlabb = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlabt = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlad = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smladx = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlald = struct {
+ const param_str = "LLiiiLLi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlaldx = struct {
+ const param_str = "LLiiiLLi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlatb = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlatt = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlawb = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlawt = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlsd = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlsdx = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlsld = struct {
+ const param_str = "LLiiiLLi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smlsldx = struct {
+ const param_str = "LLiiiLLi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smuad = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smuadx = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smulbb = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smulbt = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smultb = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smultt = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smulwb = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smulwt = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smusd = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_smusdx = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_ssat = struct {
+ const param_str = "iiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_ssat16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_ssax = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_ssub16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_ssub8 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_stc = struct {
+ const param_str = "vUIiUIiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_stc2 = struct {
+ const param_str = "vUIiUIiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_stc2l = struct {
+ const param_str = "vUIiUIiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_stcl = struct {
+ const param_str = "vUIiUIiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_stlex = struct {
+ const param_str = "i.";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_arm_strex = struct {
+ const param_str = "i.";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_arm_strexd = struct {
+ const param_str = "iLLUiv*";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_sxtab16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_sxtb16 = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_tcancel = struct {
+ const param_str = "vWUIi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_arm_tcommit = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_arm_tstart = struct {
+ const param_str = "WUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ });
+ const attributes = Attributes{
+ .returns_twice = true,
+ };
+ };
+
+ pub const __builtin_arm_ttest = struct {
+ const param_str = "WUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uadd16 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uadd8 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uasx = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uhadd16 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uhadd8 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uhasx = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uhsax = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uhsub16 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uhsub8 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uqadd16 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uqadd8 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uqasx = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uqsax = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uqsub16 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uqsub8 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_usad8 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_usada8 = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_usat = struct {
+ const param_str = "UiiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_usat16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_usax = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_usub16 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_usub8 = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uxtab16 = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_uxtb16 = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_vcvtr_d = struct {
+ const param_str = "fdi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_vcvtr_f = struct {
+ const param_str = "ffi";
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_wfe = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_wfi = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_arm_wsr = struct {
+ const param_str = "vcC*Ui";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_wsr128 = struct {
+ const param_str = "vcC*LLLUi";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_wsr64 = struct {
+ const param_str = "!";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_wsrp = struct {
+ const param_str = "vcC*vC*";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_arm_yield = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __builtin_asin = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_asinf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_asinf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_asinh = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_asinhf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_asinhf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_asinhl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_asinl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_assume = struct {
+ const param_str = "vb";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_assume_aligned = struct {
+ const param_str = "v*vC*z.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_atan = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atan2 = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atan2f = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atan2f128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atan2l = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atanf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atanf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atanh = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atanhf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atanhf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atanhl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_atanl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_bcmp = struct {
+ const param_str = "ivC*vC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bcopy = struct {
+ const param_str = "vv*v*z";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_bitrev = struct {
+ const param_str = "UiUi";
+ const target_set = TargetSet.init(.{
+ .xcore = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_bitreverse16 = struct {
+ const param_str = "UsUs";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bitreverse32 = struct {
+ const param_str = "UZiUZi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bitreverse64 = struct {
+ const param_str = "UWiUWi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bitreverse8 = struct {
+ const param_str = "UcUc";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bpermd = struct {
+ const param_str = "SLLiSLLiSLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_bswap16 = struct {
+ const param_str = "UsUs";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bswap32 = struct {
+ const param_str = "UZiUZi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bswap64 = struct {
+ const param_str = "UWiUWi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_bzero = struct {
+ const param_str = "vv*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cabs = struct {
+ const param_str = "dXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cabsf = struct {
+ const param_str = "fXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cabsl = struct {
+ const param_str = "LdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cacos = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cacosf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cacosh = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cacoshf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cacoshl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cacosl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_call_with_static_chain = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_calloc = struct {
+ const param_str = "v*zz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_canonicalize = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_canonicalizef = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_canonicalizef16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_canonicalizel = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_carg = struct {
+ const param_str = "dXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cargf = struct {
+ const param_str = "fXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cargl = struct {
+ const param_str = "LdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_casin = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_casinf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_casinh = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_casinhf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_casinhl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_casinl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_catan = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_catanf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_catanh = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_catanhf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_catanhl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_catanl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cbrt = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cbrtf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cbrtf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cbrtl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_ccos = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ccosf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ccosh = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ccoshf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ccoshl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ccosl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ceil = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_ceilf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_ceilf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_ceilf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_ceill = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cexp = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cexpf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cexpl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cfuged = struct {
+ const param_str = "ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_char_memchr = struct {
+ const param_str = "c*cC*iz";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_cimag = struct {
+ const param_str = "dXd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cimagf = struct {
+ const param_str = "fXf";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cimagl = struct {
+ const param_str = "LdXLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_classify_type = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .eval_args = false,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_clog = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_clogf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_clogl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_clrsb = struct {
+ const param_str = "ii";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_clrsbl = struct {
+ const param_str = "iLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_clrsbll = struct {
+ const param_str = "iLLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_clz = struct {
+ const param_str = "iUi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_clzl = struct {
+ const param_str = "iULi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_clzll = struct {
+ const param_str = "iULLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_clzs = struct {
+ const param_str = "iUs";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_cntlzdm = struct {
+ const param_str = "ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_cnttzdm = struct {
+ const param_str = "ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_complex = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_conj = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_conjf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_conjl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_constant_p = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .eval_args = false,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_convertvector = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_copysign = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_copysignf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_copysignf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_copysignf16 = struct {
+ const param_str = "hhh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_copysignl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_cos = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cosf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cosf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cosf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cosh = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_coshf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_coshf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_coshl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cosl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cpow = struct {
+ const param_str = "XdXdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cpowf = struct {
+ const param_str = "XfXfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cpowl = struct {
+ const param_str = "XLdXLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_cproj = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cprojf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cprojl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_cpu_init = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .x86 = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_cpu_is = struct {
+ const param_str = "bcC*";
+ const target_set = TargetSet.init(.{
+ .x86 = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_cpu_supports = struct {
+ const param_str = "bcC*";
+ const target_set = TargetSet.init(.{
+ .x86 = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_creal = struct {
+ const param_str = "dXd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_crealf = struct {
+ const param_str = "fXf";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_creall = struct {
+ const param_str = "LdXLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_csin = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csinf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csinh = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csinhf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csinhl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csinl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csqrt = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csqrtf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_csqrtl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ctan = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ctanf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ctanh = struct {
+ const param_str = "XdXd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ctanhf = struct {
+ const param_str = "XfXf";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ctanhl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ctanl = struct {
+ const param_str = "XLdXLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ctz = struct {
+ const param_str = "iUi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ctzl = struct {
+ const param_str = "iULi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ctzll = struct {
+ const param_str = "iULLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ctzs = struct {
+ const param_str = "iUs";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_darn = struct {
+ const param_str = "LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_darn_32 = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_darn_raw = struct {
+ const param_str = "LLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_dcbf = struct {
+ const param_str = "vvC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_debugtrap = struct {
+ const param_str = "v";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_divde = struct {
+ const param_str = "SLLiSLLiSLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_divdeu = struct {
+ const param_str = "ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_divf128_round_to_odd = struct {
+ const param_str = "LLdLLdLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_divwe = struct {
+ const param_str = "SiSiSi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_divweu = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_dump_struct = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_dwarf_cfa = struct {
+ const param_str = "v*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_dwarf_sp_column = struct {
+ const param_str = "Ui";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_dynamic_object_size = struct {
+ const param_str = "zvC*i";
+ const attributes = Attributes{
+ .eval_args = false,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_eh_return = struct {
+ const param_str = "vzv*";
+ const attributes = Attributes{
+ .noreturn = true,
+ };
+ };
+
+ pub const __builtin_eh_return_data_regno = struct {
+ const param_str = "iIi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_elementwise_abs = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_add_sat = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_canonicalize = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_ceil = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_copysign = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_cos = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_floor = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_max = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_min = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_roundeven = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_sin = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_sub_sat = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_elementwise_trunc = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_erf = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_erfc = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_erfcf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_erfcf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_erfcl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_erff = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_erff128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_erfl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_exp = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_exp2 = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_exp2f = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_exp2f128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_exp2f16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_exp2l = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expect = struct {
+ const param_str = "LiLiLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_expect_with_probability = struct {
+ const param_str = "LiLiLid";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_expf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expm1 = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expm1f = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expm1f128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_expm1l = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_extend_pointer = struct {
+ const param_str = "ULLiv*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_extract_return_addr = struct {
+ const param_str = "v*v*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_fabs = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fabsf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fabsf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fabsf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_fabsl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fdim = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fdimf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fdimf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fdiml = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ffs = struct {
+ const param_str = "ii";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ffsl = struct {
+ const param_str = "iLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ffsll = struct {
+ const param_str = "iLLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_floor = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_floorf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_floorf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_floorf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_floorl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_flt_rounds = struct {
+ const param_str = "i";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_fma = struct {
+ const param_str = "dddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmaf = struct {
+ const param_str = "ffff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmaf128 = struct {
+ const param_str = "LLdLLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmaf128_round_to_odd = struct {
+ const param_str = "LLdLLdLLdLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_fmaf16 = struct {
+ const param_str = "hhhh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmal = struct {
+ const param_str = "LdLdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmax = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fmaxf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fmaxf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fmaxf16 = struct {
+ const param_str = "hhh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fmaxl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fmin = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fminf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fminf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fminf16 = struct {
+ const param_str = "hhh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fminl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fmod = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmodf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmodf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmodf16 = struct {
+ const param_str = "hhh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fmodl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_fpclassify = struct {
+ const param_str = "iiiiii.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_fprintf = struct {
+ const param_str = "iP*cC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const __builtin_frame_address = struct {
+ const param_str = "v*IUi";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_free = struct {
+ const param_str = "vv*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_frexp = struct {
+ const param_str = "ddi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_frexpf = struct {
+ const param_str = "ffi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_frexpf128 = struct {
+ const param_str = "LLdLLdi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_frexpl = struct {
+ const param_str = "LdLdi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_frob_return_addr = struct {
+ const param_str = "v*v*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_get_texasr = struct {
+ const param_str = "LUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_get_texasru = struct {
+ const param_str = "LUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_get_tfhar = struct {
+ const param_str = "LUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_get_tfiar = struct {
+ const param_str = "LUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_getid = struct {
+ const param_str = "Si";
+ const target_set = TargetSet.init(.{
+ .xcore = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_getps = struct {
+ const param_str = "UiUi";
+ const target_set = TargetSet.init(.{
+ .xcore = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_huge_val = struct {
+ const param_str = "d";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_huge_valf = struct {
+ const param_str = "f";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_huge_valf128 = struct {
+ const param_str = "LLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_huge_valf16 = struct {
+ const param_str = "x";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_huge_vall = struct {
+ const param_str = "Ld";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_hypot = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_hypotf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_hypotf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_hypotl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ia32_rdpmc = struct {
+ const param_str = "UOii";
+ const target_set = TargetSet.init(.{
+ .x86 = true,
+ });
+ };
+
+ pub const __builtin_ia32_rdtsc = struct {
+ const param_str = "UOi";
+ const target_set = TargetSet.init(.{
+ .x86 = true,
+ });
+ };
+
+ pub const __builtin_ia32_rdtscp = struct {
+ const param_str = "UOiUi*";
+ const target_set = TargetSet.init(.{
+ .x86 = true,
+ });
+ };
+
+ pub const __builtin_ilogb = struct {
+ const param_str = "id";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ilogbf = struct {
+ const param_str = "if";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ilogbf128 = struct {
+ const param_str = "iLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ilogbl = struct {
+ const param_str = "iLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_index = struct {
+ const param_str = "c*cC*i";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_inf = struct {
+ const param_str = "d";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_inff = struct {
+ const param_str = "f";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_inff128 = struct {
+ const param_str = "LLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_inff16 = struct {
+ const param_str = "x";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_infl = struct {
+ const param_str = "Ld";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_init_dwarf_reg_size_table = struct {
+ const param_str = "vv*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_is_aligned = struct {
+ const param_str = "bvC*z";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_isfinite = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_isgreater = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_isgreaterequal = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_isinf = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_isinf_sign = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_isless = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_islessequal = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_islessgreater = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_isnan = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_isnormal = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_isunordered = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_labs = struct {
+ const param_str = "LiLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_launder = struct {
+ const param_str = "v*v*";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ldexp = struct {
+ const param_str = "ddi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ldexpf = struct {
+ const param_str = "ffi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ldexpf128 = struct {
+ const param_str = "LLdLLdi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ldexpl = struct {
+ const param_str = "LdLdi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lgamma = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_lgammaf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_lgammaf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_lgammal = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_llabs = struct {
+ const param_str = "LLiLLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_llrint = struct {
+ const param_str = "LLid";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_llrintf = struct {
+ const param_str = "LLif";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_llrintf128 = struct {
+ const param_str = "LLiLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_llrintl = struct {
+ const param_str = "LLiLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_llround = struct {
+ const param_str = "LLid";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_llroundf = struct {
+ const param_str = "LLif";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_llroundf128 = struct {
+ const param_str = "LLiLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_llroundl = struct {
+ const param_str = "LLiLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log10 = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log10f = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log10f128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log10f16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log10l = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log1p = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log1pf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log1pf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log1pl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log2 = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log2f = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log2f128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log2f16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_log2l = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logb = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logbf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logbf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logbl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_logl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_longjmp = struct {
+ const param_str = "vv**i";
+ const attributes = Attributes{
+ .noreturn = true,
+ };
+ };
+
+ pub const __builtin_lrint = struct {
+ const param_str = "Lid";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lrintf = struct {
+ const param_str = "Lif";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lrintf128 = struct {
+ const param_str = "LiLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lrintl = struct {
+ const param_str = "LiLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lround = struct {
+ const param_str = "Lid";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lroundf = struct {
+ const param_str = "Lif";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lroundf128 = struct {
+ const param_str = "LiLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_lroundl = struct {
+ const param_str = "LiLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_malloc = struct {
+ const param_str = "v*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_matrix_column_major_load = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_matrix_column_major_store = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_matrix_transpose = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_memchr = struct {
+ const param_str = "v*vC*iz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_memcmp = struct {
+ const param_str = "ivC*vC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_memcpy = struct {
+ const param_str = "v*v*vC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_memcpy_inline = struct {
+ const param_str = "vv*vC*Iz";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_memmove = struct {
+ const param_str = "v*v*vC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_mempcpy = struct {
+ const param_str = "v*v*vC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_memset = struct {
+ const param_str = "v*v*iz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_memset_inline = struct {
+ const param_str = "vv*iIz";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_absq_s_ph = struct {
+ const param_str = "V2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_absq_s_qb = struct {
+ const param_str = "V4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_absq_s_w = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addq_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addq_s_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addq_s_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addqh_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_addqh_r_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_addqh_r_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_addqh_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_addsc = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addu_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addu_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addu_s_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_addu_s_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_adduh_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_adduh_r_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_addwc = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_append = struct {
+ const param_str = "iiiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_balign = struct {
+ const param_str = "iiiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_bitrev = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_bposge32 = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmp_eq_ph = struct {
+ const param_str = "vV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmp_le_ph = struct {
+ const param_str = "vV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmp_lt_ph = struct {
+ const param_str = "vV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpgdu_eq_qb = struct {
+ const param_str = "iV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpgdu_le_qb = struct {
+ const param_str = "iV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpgdu_lt_qb = struct {
+ const param_str = "iV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpgu_eq_qb = struct {
+ const param_str = "iV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpgu_le_qb = struct {
+ const param_str = "iV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpgu_lt_qb = struct {
+ const param_str = "iV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpu_eq_qb = struct {
+ const param_str = "vV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpu_le_qb = struct {
+ const param_str = "vV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_cmpu_lt_qb = struct {
+ const param_str = "vV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpa_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_dpaq_s_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpaq_sa_l_w = struct {
+ const param_str = "LLiLLiii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpaqx_s_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpaqx_sa_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpau_h_qbl = struct {
+ const param_str = "LLiLLiV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_dpau_h_qbr = struct {
+ const param_str = "LLiLLiV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_dpax_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_dps_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_dpsq_s_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpsq_sa_l_w = struct {
+ const param_str = "LLiLLiii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpsqx_s_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpsqx_sa_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_dpsu_h_qbl = struct {
+ const param_str = "LLiLLiV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_dpsu_h_qbr = struct {
+ const param_str = "LLiLLiV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_dpsx_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_extp = struct {
+ const param_str = "iLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_extpdp = struct {
+ const param_str = "iLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_extr_r_w = struct {
+ const param_str = "iLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_extr_rs_w = struct {
+ const param_str = "iLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_extr_s_h = struct {
+ const param_str = "iLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_extr_w = struct {
+ const param_str = "iLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_insv = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_lbux = struct {
+ const param_str = "iv*i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_lhx = struct {
+ const param_str = "iv*i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_lwx = struct {
+ const param_str = "iv*i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_madd = struct {
+ const param_str = "LLiLLiii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_maddu = struct {
+ const param_str = "LLiLLiUiUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_maq_s_w_phl = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_maq_s_w_phr = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_maq_sa_w_phl = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_maq_sa_w_phr = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_modsub = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_msub = struct {
+ const param_str = "LLiLLiii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_msubu = struct {
+ const param_str = "LLiLLiUiUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_mthlip = struct {
+ const param_str = "LLiLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mul_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mul_s_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_muleq_s_w_phl = struct {
+ const param_str = "iV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_muleq_s_w_phr = struct {
+ const param_str = "iV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_muleu_s_ph_qbl = struct {
+ const param_str = "V2sV4ScV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_muleu_s_ph_qbr = struct {
+ const param_str = "V2sV4ScV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mulq_rs_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mulq_rs_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mulq_s_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mulq_s_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mulsa_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_mulsaq_s_w_ph = struct {
+ const param_str = "LLiLLiV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_mult = struct {
+ const param_str = "LLiii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_multu = struct {
+ const param_str = "LLiUiUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_packrl_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_pick_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_pick_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_preceq_w_phl = struct {
+ const param_str = "iV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_preceq_w_phr = struct {
+ const param_str = "iV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precequ_ph_qbl = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precequ_ph_qbla = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precequ_ph_qbr = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precequ_ph_qbra = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_preceu_ph_qbl = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_preceu_ph_qbla = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_preceu_ph_qbr = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_preceu_ph_qbra = struct {
+ const param_str = "V2sV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precr_qb_ph = struct {
+ const param_str = "V4ScV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_precr_sra_ph_w = struct {
+ const param_str = "V2siiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precr_sra_r_ph_w = struct {
+ const param_str = "V2siiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precrq_ph_w = struct {
+ const param_str = "V2sii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precrq_qb_ph = struct {
+ const param_str = "V4ScV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_precrq_rs_ph_w = struct {
+ const param_str = "V2sii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_precrqu_s_qb_ph = struct {
+ const param_str = "V4ScV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_prepend = struct {
+ const param_str = "iiiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_raddu_w_qb = struct {
+ const param_str = "iV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_rddsp = struct {
+ const param_str = "iIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_repl_ph = struct {
+ const param_str = "V2si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_repl_qb = struct {
+ const param_str = "V4Sci";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shilo = struct {
+ const param_str = "LLiLLii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shll_ph = struct {
+ const param_str = "V2sV2si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_shll_qb = struct {
+ const param_str = "V4ScV4Sci";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_shll_s_ph = struct {
+ const param_str = "V2sV2si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_shll_s_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_shra_ph = struct {
+ const param_str = "V2sV2si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shra_qb = struct {
+ const param_str = "V4ScV4Sci";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shra_r_ph = struct {
+ const param_str = "V2sV2si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shra_r_qb = struct {
+ const param_str = "V4ScV4Sci";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shra_r_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shrl_ph = struct {
+ const param_str = "V2sV2si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_shrl_qb = struct {
+ const param_str = "V4ScV4Sci";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_subq_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_subq_s_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_subq_s_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_subqh_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_subqh_r_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_subqh_r_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_subqh_w = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_subu_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_subu_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_subu_s_ph = struct {
+ const param_str = "V2sV2sV2s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_subu_s_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_mips_subuh_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_subuh_r_qb = struct {
+ const param_str = "V4ScV4ScV4Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mips_wrdsp = struct {
+ const param_str = "viIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_modf = struct {
+ const param_str = "ddd*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_modff = struct {
+ const param_str = "fff*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_modff128 = struct {
+ const param_str = "LLdLLdLLd*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_modfl = struct {
+ const param_str = "LdLdLd*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_msa_add_a_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_add_a_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_add_a_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_add_a_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_a_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_a_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_a_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_a_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_adds_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addv_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addv_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addv_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addv_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addvi_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addvi_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addvi_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_addvi_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_and_v = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_andi_b = struct {
+ const param_str = "V16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_asub_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ave_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_aver_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclr_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclr_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclr_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclr_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclri_b = struct {
+ const param_str = "V16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclri_d = struct {
+ const param_str = "V2ULLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclri_h = struct {
+ const param_str = "V8UsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bclri_w = struct {
+ const param_str = "V4UiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsl_b = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsl_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsl_h = struct {
+ const param_str = "V8UsV8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsl_w = struct {
+ const param_str = "V4UiV4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsli_b = struct {
+ const param_str = "V16UcV16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsli_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsli_h = struct {
+ const param_str = "V8UsV8UsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsli_w = struct {
+ const param_str = "V4UiV4UiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsr_b = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsr_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsr_h = struct {
+ const param_str = "V8UsV8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsr_w = struct {
+ const param_str = "V4UiV4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsri_b = struct {
+ const param_str = "V16UcV16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsri_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsri_h = struct {
+ const param_str = "V8UsV8UsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_binsri_w = struct {
+ const param_str = "V4UiV4UiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bmnz_v = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bmnzi_b = struct {
+ const param_str = "V16UcV16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bmz_v = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bmzi_b = struct {
+ const param_str = "V16UcV16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bneg_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bneg_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bneg_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bneg_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnegi_b = struct {
+ const param_str = "V16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnegi_d = struct {
+ const param_str = "V2ULLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnegi_h = struct {
+ const param_str = "V8UsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnegi_w = struct {
+ const param_str = "V4UiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnz_b = struct {
+ const param_str = "iV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnz_d = struct {
+ const param_str = "iV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnz_h = struct {
+ const param_str = "iV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnz_v = struct {
+ const param_str = "iV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bnz_w = struct {
+ const param_str = "iV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bsel_v = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bseli_b = struct {
+ const param_str = "V16UcV16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bset_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bset_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bset_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bset_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bseti_b = struct {
+ const param_str = "V16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bseti_d = struct {
+ const param_str = "V2ULLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bseti_h = struct {
+ const param_str = "V8UsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bseti_w = struct {
+ const param_str = "V4UiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bz_b = struct {
+ const param_str = "iV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bz_d = struct {
+ const param_str = "iV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bz_h = struct {
+ const param_str = "iV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bz_v = struct {
+ const param_str = "iV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_bz_w = struct {
+ const param_str = "iV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceq_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceq_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceq_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceq_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceqi_b = struct {
+ const param_str = "V16ScV16ScISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceqi_d = struct {
+ const param_str = "V2SLLiV2SLLiISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceqi_h = struct {
+ const param_str = "V8SsV8SsISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ceqi_w = struct {
+ const param_str = "V4SiV4SiISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cfcmsa = struct {
+ const param_str = "iIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_msa_cle_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cle_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cle_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cle_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cle_u_b = struct {
+ const param_str = "V16ScV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cle_u_d = struct {
+ const param_str = "V2SLLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cle_u_h = struct {
+ const param_str = "V8SsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_cle_u_w = struct {
+ const param_str = "V4SiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_s_b = struct {
+ const param_str = "V16ScV16ScISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_s_d = struct {
+ const param_str = "V2SLLiV2SLLiISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_s_h = struct {
+ const param_str = "V8SsV8SsISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_s_w = struct {
+ const param_str = "V4SiV4SiISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_u_b = struct {
+ const param_str = "V16ScV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_u_d = struct {
+ const param_str = "V2SLLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_u_h = struct {
+ const param_str = "V8SsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clei_u_w = struct {
+ const param_str = "V4SiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_u_b = struct {
+ const param_str = "V16ScV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_u_d = struct {
+ const param_str = "V2SLLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_u_h = struct {
+ const param_str = "V8SsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clt_u_w = struct {
+ const param_str = "V4SiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_s_b = struct {
+ const param_str = "V16ScV16ScISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_s_d = struct {
+ const param_str = "V2SLLiV2SLLiISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_s_h = struct {
+ const param_str = "V8SsV8SsISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_s_w = struct {
+ const param_str = "V4SiV4SiISi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_u_b = struct {
+ const param_str = "V16ScV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_u_d = struct {
+ const param_str = "V2SLLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_u_h = struct {
+ const param_str = "V8SsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_clti_u_w = struct {
+ const param_str = "V4SiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_s_b = struct {
+ const param_str = "iV16ScIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_s_d = struct {
+ const param_str = "LLiV2SLLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_s_h = struct {
+ const param_str = "iV8SsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_s_w = struct {
+ const param_str = "iV4SiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_u_b = struct {
+ const param_str = "iV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_u_d = struct {
+ const param_str = "LLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_u_h = struct {
+ const param_str = "iV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_copy_u_w = struct {
+ const param_str = "iV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ctcmsa = struct {
+ const param_str = "vIii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_msa_div_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_div_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_div_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_div_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_div_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_div_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_div_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_div_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dotp_s_d = struct {
+ const param_str = "V2SLLiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dotp_s_h = struct {
+ const param_str = "V8SsV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dotp_s_w = struct {
+ const param_str = "V4SiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dotp_u_d = struct {
+ const param_str = "V2ULLiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dotp_u_h = struct {
+ const param_str = "V8UsV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dotp_u_w = struct {
+ const param_str = "V4UiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpadd_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpadd_s_h = struct {
+ const param_str = "V8SsV8SsV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpadd_s_w = struct {
+ const param_str = "V4SiV4SiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpadd_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpadd_u_h = struct {
+ const param_str = "V8UsV8UsV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpadd_u_w = struct {
+ const param_str = "V4UiV4UiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpsub_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpsub_s_h = struct {
+ const param_str = "V8SsV8SsV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpsub_s_w = struct {
+ const param_str = "V4SiV4SiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpsub_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpsub_u_h = struct {
+ const param_str = "V8UsV8UsV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_dpsub_u_w = struct {
+ const param_str = "V4UiV4UiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fadd_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fadd_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcaf_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcaf_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fceq_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fceq_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fclass_d = struct {
+ const param_str = "V2LLiV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fclass_w = struct {
+ const param_str = "V4iV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcle_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcle_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fclt_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fclt_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcne_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcne_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcor_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcor_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcueq_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcueq_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcule_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcule_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcult_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcult_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcun_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcun_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcune_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fcune_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fdiv_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fdiv_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexdo_h = struct {
+ const param_str = "V8hV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexdo_w = struct {
+ const param_str = "V4fV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexp2_d = struct {
+ const param_str = "V2dV2dV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexp2_w = struct {
+ const param_str = "V4fV4fV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexupl_d = struct {
+ const param_str = "V2dV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexupl_w = struct {
+ const param_str = "V4fV8h";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexupr_d = struct {
+ const param_str = "V2dV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fexupr_w = struct {
+ const param_str = "V4fV8h";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffint_s_d = struct {
+ const param_str = "V2dV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffint_s_w = struct {
+ const param_str = "V4fV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffint_u_d = struct {
+ const param_str = "V2dV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffint_u_w = struct {
+ const param_str = "V4fV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffql_d = struct {
+ const param_str = "V2dV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffql_w = struct {
+ const param_str = "V4fV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffqr_d = struct {
+ const param_str = "V2dV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ffqr_w = struct {
+ const param_str = "V4fV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fill_b = struct {
+ const param_str = "V16Sci";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fill_d = struct {
+ const param_str = "V2SLLiLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fill_h = struct {
+ const param_str = "V8Ssi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fill_w = struct {
+ const param_str = "V4Sii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_flog2_d = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_flog2_w = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmadd_d = struct {
+ const param_str = "V2dV2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmadd_w = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmax_a_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmax_a_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmax_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmax_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmin_a_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmin_a_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmin_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmin_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmsub_d = struct {
+ const param_str = "V2dV2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmsub_w = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmul_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fmul_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_frcp_d = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_frcp_w = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_frint_d = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_frint_w = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_frsqrt_d = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_frsqrt_w = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsaf_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsaf_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fseq_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fseq_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsle_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsle_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fslt_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fslt_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsne_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsne_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsor_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsor_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsqrt_d = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsqrt_w = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsub_d = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsub_w = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsueq_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsueq_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsule_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsule_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsult_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsult_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsun_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsun_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsune_d = struct {
+ const param_str = "V2LLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_fsune_w = struct {
+ const param_str = "V4iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftint_s_d = struct {
+ const param_str = "V2SLLiV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftint_s_w = struct {
+ const param_str = "V4SiV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftint_u_d = struct {
+ const param_str = "V2ULLiV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftint_u_w = struct {
+ const param_str = "V4UiV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftq_h = struct {
+ const param_str = "V4UiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftq_w = struct {
+ const param_str = "V2ULLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftrunc_s_d = struct {
+ const param_str = "V2SLLiV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftrunc_s_w = struct {
+ const param_str = "V4SiV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftrunc_u_d = struct {
+ const param_str = "V2ULLiV2d";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ftrunc_u_w = struct {
+ const param_str = "V4UiV4f";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hadd_s_d = struct {
+ const param_str = "V2SLLiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hadd_s_h = struct {
+ const param_str = "V8SsV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hadd_s_w = struct {
+ const param_str = "V4SiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hadd_u_d = struct {
+ const param_str = "V2ULLiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hadd_u_h = struct {
+ const param_str = "V8UsV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hadd_u_w = struct {
+ const param_str = "V4UiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hsub_s_d = struct {
+ const param_str = "V2SLLiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hsub_s_h = struct {
+ const param_str = "V8SsV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hsub_s_w = struct {
+ const param_str = "V4SiV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hsub_u_d = struct {
+ const param_str = "V2ULLiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hsub_u_h = struct {
+ const param_str = "V8UsV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_hsub_u_w = struct {
+ const param_str = "V4UiV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvev_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvev_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvev_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvev_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvl_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvl_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvl_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvl_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvod_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvod_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvod_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvod_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvr_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvr_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvr_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ilvr_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insert_b = struct {
+ const param_str = "V16ScV16ScIUii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insert_d = struct {
+ const param_str = "V2SLLiV2SLLiIUiLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insert_h = struct {
+ const param_str = "V8SsV8SsIUii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insert_w = struct {
+ const param_str = "V4SiV4SiIUii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insve_b = struct {
+ const param_str = "V16ScV16ScIUiV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insve_d = struct {
+ const param_str = "V2SLLiV2SLLiIUiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insve_h = struct {
+ const param_str = "V8SsV8SsIUiV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_insve_w = struct {
+ const param_str = "V4SiV4SiIUiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ld_b = struct {
+ const param_str = "V16Scv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ld_d = struct {
+ const param_str = "V2SLLiv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ld_h = struct {
+ const param_str = "V8Ssv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ld_w = struct {
+ const param_str = "V4Siv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ldi_b = struct {
+ const param_str = "V16cIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ldi_d = struct {
+ const param_str = "V2LLiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ldi_h = struct {
+ const param_str = "V8sIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ldi_w = struct {
+ const param_str = "V4iIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ldr_d = struct {
+ const param_str = "V2SLLiv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ldr_w = struct {
+ const param_str = "V4Siv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_madd_q_h = struct {
+ const param_str = "V8SsV8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_madd_q_w = struct {
+ const param_str = "V4SiV4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maddr_q_h = struct {
+ const param_str = "V8SsV8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maddr_q_w = struct {
+ const param_str = "V4SiV4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maddv_b = struct {
+ const param_str = "V16ScV16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maddv_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maddv_h = struct {
+ const param_str = "V8SsV8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maddv_w = struct {
+ const param_str = "V4SiV4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_a_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_a_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_a_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_a_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_max_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_s_b = struct {
+ const param_str = "V16ScV16ScIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_s_d = struct {
+ const param_str = "V2SLLiV2SLLiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_s_h = struct {
+ const param_str = "V8SsV8SsIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_s_w = struct {
+ const param_str = "V4SiV4SiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_u_b = struct {
+ const param_str = "V16UcV16UcIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_u_d = struct {
+ const param_str = "V2ULLiV2ULLiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_u_h = struct {
+ const param_str = "V8UsV8UsIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_maxi_u_w = struct {
+ const param_str = "V4UiV4UiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_a_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_a_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_a_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_a_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_min_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_s_b = struct {
+ const param_str = "V16ScV16ScIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_s_d = struct {
+ const param_str = "V2SLLiV2SLLiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_s_h = struct {
+ const param_str = "V8SsV8SsIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_s_w = struct {
+ const param_str = "V4SiV4SiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_u_b = struct {
+ const param_str = "V16UcV16UcIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_u_d = struct {
+ const param_str = "V2ULLiV2ULLiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_u_h = struct {
+ const param_str = "V8UsV8UsIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mini_u_w = struct {
+ const param_str = "V4UiV4UiIi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mod_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_move_v = struct {
+ const param_str = "V16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msub_q_h = struct {
+ const param_str = "V8SsV8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msub_q_w = struct {
+ const param_str = "V4SiV4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msubr_q_h = struct {
+ const param_str = "V8SsV8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msubr_q_w = struct {
+ const param_str = "V4SiV4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msubv_b = struct {
+ const param_str = "V16ScV16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msubv_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msubv_h = struct {
+ const param_str = "V8SsV8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_msubv_w = struct {
+ const param_str = "V4SiV4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mul_q_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mul_q_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mulr_q_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mulr_q_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mulv_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mulv_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mulv_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_mulv_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nloc_b = struct {
+ const param_str = "V16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nloc_d = struct {
+ const param_str = "V2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nloc_h = struct {
+ const param_str = "V8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nloc_w = struct {
+ const param_str = "V4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nlzc_b = struct {
+ const param_str = "V16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nlzc_d = struct {
+ const param_str = "V2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nlzc_h = struct {
+ const param_str = "V8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nlzc_w = struct {
+ const param_str = "V4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nor_v = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_nori_b = struct {
+ const param_str = "V16UcV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_or_v = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_ori_b = struct {
+ const param_str = "V16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckev_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckev_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckev_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckev_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckod_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckod_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckod_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pckod_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pcnt_b = struct {
+ const param_str = "V16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pcnt_d = struct {
+ const param_str = "V2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pcnt_h = struct {
+ const param_str = "V8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_pcnt_w = struct {
+ const param_str = "V4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_s_b = struct {
+ const param_str = "V16ScV16ScIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_s_d = struct {
+ const param_str = "V2SLLiV2SLLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_s_h = struct {
+ const param_str = "V8SsV8SsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_s_w = struct {
+ const param_str = "V4SiV4SiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_u_b = struct {
+ const param_str = "V16UcV16UcIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_u_d = struct {
+ const param_str = "V2ULLiV2ULLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_u_h = struct {
+ const param_str = "V8UsV8UsIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sat_u_w = struct {
+ const param_str = "V4UiV4UiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_shf_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_shf_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_shf_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sld_b = struct {
+ const param_str = "V16cV16cV16cUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sld_d = struct {
+ const param_str = "V2LLiV2LLiV2LLiUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sld_h = struct {
+ const param_str = "V8sV8sV8sUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sld_w = struct {
+ const param_str = "V4iV4iV4iUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sldi_b = struct {
+ const param_str = "V16cV16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sldi_d = struct {
+ const param_str = "V2LLiV2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sldi_h = struct {
+ const param_str = "V8sV8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sldi_w = struct {
+ const param_str = "V4iV4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sll_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sll_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sll_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sll_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_slli_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_slli_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_slli_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_slli_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splat_b = struct {
+ const param_str = "V16cV16cUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splat_d = struct {
+ const param_str = "V2LLiV2LLiUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splat_h = struct {
+ const param_str = "V8sV8sUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splat_w = struct {
+ const param_str = "V4iV4iUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splati_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splati_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splati_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_splati_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sra_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sra_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sra_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_sra_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srai_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srai_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srai_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srai_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srar_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srar_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srar_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srar_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srari_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srari_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srari_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srari_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srl_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srl_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srl_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srl_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srli_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srli_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srli_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srli_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlr_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlr_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlr_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlr_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlri_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlri_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlri_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_srlri_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_st_b = struct {
+ const param_str = "vV16Scv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_st_d = struct {
+ const param_str = "vV2SLLiv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_st_h = struct {
+ const param_str = "vV8Ssv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_st_w = struct {
+ const param_str = "vV4Siv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_str_d = struct {
+ const param_str = "vV2SLLiv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_str_w = struct {
+ const param_str = "vV4Siv*Ii";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_s_b = struct {
+ const param_str = "V16ScV16ScV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_s_d = struct {
+ const param_str = "V2SLLiV2SLLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_s_h = struct {
+ const param_str = "V8SsV8SsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_s_w = struct {
+ const param_str = "V4SiV4SiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_u_b = struct {
+ const param_str = "V16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_u_h = struct {
+ const param_str = "V8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subs_u_w = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsus_u_b = struct {
+ const param_str = "V16UcV16UcV16Sc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsus_u_d = struct {
+ const param_str = "V2ULLiV2ULLiV2SLLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsus_u_h = struct {
+ const param_str = "V8UsV8UsV8Ss";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsus_u_w = struct {
+ const param_str = "V4UiV4UiV4Si";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsuu_s_b = struct {
+ const param_str = "V16ScV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsuu_s_d = struct {
+ const param_str = "V2SLLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsuu_s_h = struct {
+ const param_str = "V8SsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subsuu_s_w = struct {
+ const param_str = "V4SiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subv_b = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subv_d = struct {
+ const param_str = "V2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subv_h = struct {
+ const param_str = "V8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subv_w = struct {
+ const param_str = "V4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subvi_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subvi_d = struct {
+ const param_str = "V2LLiV2LLiIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subvi_h = struct {
+ const param_str = "V8sV8sIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_subvi_w = struct {
+ const param_str = "V4iV4iIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_vshf_b = struct {
+ const param_str = "V16cV16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_vshf_d = struct {
+ const param_str = "V2LLiV2LLiV2LLiV2LLi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_vshf_h = struct {
+ const param_str = "V8sV8sV8sV8s";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_vshf_w = struct {
+ const param_str = "V4iV4iV4iV4i";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_xor_v = struct {
+ const param_str = "V16cV16cV16c";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_msa_xori_b = struct {
+ const param_str = "V16cV16cIUi";
+ const target_set = TargetSet.init(.{
+ .mips = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_mul_overflow = struct {
+ const param_str = "b.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_mulf128_round_to_odd = struct {
+ const param_str = "LLdLLdLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_nan = struct {
+ const param_str = "dcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nanf = struct {
+ const param_str = "fcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nanf128 = struct {
+ const param_str = "LLdcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nanf16 = struct {
+ const param_str = "xcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nanl = struct {
+ const param_str = "LdcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nans = struct {
+ const param_str = "dcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nansf = struct {
+ const param_str = "fcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nansf128 = struct {
+ const param_str = "LLdcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nansf16 = struct {
+ const param_str = "xcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nansl = struct {
+ const param_str = "LdcC*";
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_nearbyint = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_nearbyintf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_nearbyintf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_nearbyintl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_nextafter = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nextafterf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nextafterf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nextafterl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nexttoward = struct {
+ const param_str = "ddLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nexttowardf = struct {
+ const param_str = "ffLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nexttowardf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nexttowardl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_nontemporal_load = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_nontemporal_store = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_objc_memmove_collectable = struct {
+ const param_str = "v*v*vC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_object_size = struct {
+ const param_str = "zvC*i";
+ const attributes = Attributes{
+ .eval_args = false,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_operator_delete = struct {
+ const param_str = "vv*";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_operator_new = struct {
+ const param_str = "v*z";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_os_log_format = struct {
+ const param_str = "v*v*cC*.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .format_kind = .printf,
+ .format_string_position = 0,
+ };
+ };
+
+ pub const __builtin_os_log_format_buffer_size = struct {
+ const param_str = "zcC*.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .eval_args = false,
+ .const_evaluable = true,
+ .format_kind = .printf,
+ .format_string_position = 0,
+ };
+ };
+
+ pub const __builtin_pack_longdouble = struct {
+ const param_str = "Lddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_pack_vector_int128 = struct {
+ const param_str = "V1LLLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_parity = struct {
+ const param_str = "iUi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_parityl = struct {
+ const param_str = "iULi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_parityll = struct {
+ const param_str = "iULLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_pdepd = struct {
+ const param_str = "ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_pextd = struct {
+ const param_str = "ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_popcount = struct {
+ const param_str = "iUi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_popcountl = struct {
+ const param_str = "iULi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_popcountll = struct {
+ const param_str = "iULLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_pow = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_powf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_powf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_powf16 = struct {
+ const param_str = "hhh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_powi = struct {
+ const param_str = "ddi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_powif = struct {
+ const param_str = "ffi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_powil = struct {
+ const param_str = "LdLdi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_powl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ppc_addex = struct {
+ const param_str = "LLiLLiLLiCIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_alignx = struct {
+ const param_str = "vIivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_ppc_bcdadd = struct {
+ const param_str = "V16UcV16UcV16UcIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_bcdadd_p = struct {
+ const param_str = "iiV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_bcdsub = struct {
+ const param_str = "V16UcV16UcV16UcIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_bcdsub_p = struct {
+ const param_str = "iiV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_cmpb = struct {
+ const param_str = "LLiLLiLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_cmpeqb = struct {
+ const param_str = "LLiLLiLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_cmprb = struct {
+ const param_str = "iCIiii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_compare_and_swap = struct {
+ const param_str = "iiD*i*i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_compare_and_swaplp = struct {
+ const param_str = "iLiD*Li*Li";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_compare_exp_eq = struct {
+ const param_str = "idd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_compare_exp_gt = struct {
+ const param_str = "idd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_compare_exp_lt = struct {
+ const param_str = "idd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_compare_exp_uo = struct {
+ const param_str = "idd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbfl = struct {
+ const param_str = "vvC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbflp = struct {
+ const param_str = "vvC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbst = struct {
+ const param_str = "vvC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbt = struct {
+ const param_str = "vv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbtst = struct {
+ const param_str = "vv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbtstt = struct {
+ const param_str = "vv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbtt = struct {
+ const param_str = "vv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_dcbz = struct {
+ const param_str = "vv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_eieio = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_extract_exp = struct {
+ const param_str = "Uid";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_extract_sig = struct {
+ const param_str = "ULLid";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fcfid = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fcfud = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fctid = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fctidz = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fctiw = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fctiwz = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fctudz = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fctuwz = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_add = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_addlp = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_and = struct {
+ const param_str = "UiUiD*Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_andlp = struct {
+ const param_str = "ULiULiD*ULi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_or = struct {
+ const param_str = "UiUiD*Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_orlp = struct {
+ const param_str = "ULiULiD*ULi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_swap = struct {
+ const param_str = "UiUiD*Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fetch_and_swaplp = struct {
+ const param_str = "ULiULiD*ULi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fmsub = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fmsubs = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fnabs = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fnabss = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fnmadd = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fnmadds = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fnmsub = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fnmsubs = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fre = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fres = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fric = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frim = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frims = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frin = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frins = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frip = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frips = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_friz = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frizs = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frsqrte = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_frsqrtes = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fsel = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fsels = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fsqrt = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_fsqrts = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_get_timebase = struct {
+ const param_str = "ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ppc_icbt = struct {
+ const param_str = "vv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_insert_exp = struct {
+ const param_str = "ddULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_iospace_eieio = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_iospace_lwsync = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_iospace_sync = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_isync = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_lbarx = struct {
+ const param_str = "ccD*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_ldarx = struct {
+ const param_str = "LiLiD*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_lharx = struct {
+ const param_str = "ssD*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_load2r = struct {
+ const param_str = "UsUs*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_load4r = struct {
+ const param_str = "UiUi*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_load8r = struct {
+ const param_str = "ULLiULLi*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_lwarx = struct {
+ const param_str = "iiD*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_lwsync = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_maddhd = struct {
+ const param_str = "LLiLLiLLiLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_maddhdu = struct {
+ const param_str = "ULLiULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_maddld = struct {
+ const param_str = "LLiLLiLLiLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_maxfe = struct {
+ const param_str = "LdLdLdLd.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ppc_maxfl = struct {
+ const param_str = "dddd.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ppc_maxfs = struct {
+ const param_str = "ffff.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ppc_mfmsr = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mfspr = struct {
+ const param_str = "ULiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mftbu = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_minfe = struct {
+ const param_str = "LdLdLdLd.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ppc_minfl = struct {
+ const param_str = "dddd.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ppc_minfs = struct {
+ const param_str = "ffff.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ppc_mtfsb0 = struct {
+ const param_str = "vUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mtfsb1 = struct {
+ const param_str = "vUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mtfsf = struct {
+ const param_str = "vUIiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mtfsfi = struct {
+ const param_str = "vUIiUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mtmsr = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mtspr = struct {
+ const param_str = "vIiULi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mulhd = struct {
+ const param_str = "LLiLiLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mulhdu = struct {
+ const param_str = "ULLiULiULi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mulhw = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_mulhwu = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_popcntb = struct {
+ const param_str = "ULiULi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_poppar4 = struct {
+ const param_str = "iUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_poppar8 = struct {
+ const param_str = "iULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_rdlam = struct {
+ const param_str = "UWiUWiUWiUWIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_ppc_recipdivd = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_recipdivf = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_rldimi = struct {
+ const param_str = "ULLiULLiULLiIUiIULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_rlwimi = struct {
+ const param_str = "UiUiUiIUiIUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_rlwnm = struct {
+ const param_str = "UiUiUiIUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_rsqrtd = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_rsqrtf = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_setb = struct {
+ const param_str = "LLiLLiLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_stbcx = struct {
+ const param_str = "icD*i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_stdcx = struct {
+ const param_str = "iLiD*Li";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_stfiw = struct {
+ const param_str = "viC*d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_sthcx = struct {
+ const param_str = "isD*s";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_store2r = struct {
+ const param_str = "vUiUs*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_store4r = struct {
+ const param_str = "vUiUi*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_store8r = struct {
+ const param_str = "vULLiULLi*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_stwcx = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_swdiv = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_swdiv_nochk = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_swdivs = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_swdivs_nochk = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_sync = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_tdw = struct {
+ const param_str = "vLLiLLiIUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_test_data_class = struct {
+ const param_str = "idIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ppc_trap = struct {
+ const param_str = "vi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_trapd = struct {
+ const param_str = "vLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ppc_tw = struct {
+ const param_str = "viiIUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_prefetch = struct {
+ const param_str = "vvC*.";
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_preserve_access_index = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_printf = struct {
+ const param_str = "icC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 0,
+ };
+ };
+
+ pub const __builtin_ptx_get_image_channel_data_typei_ = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_get_image_channel_orderi_ = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_get_image_depthi_ = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_get_image_heighti_ = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_get_image_widthi_ = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image2Dff_ = struct {
+ const param_str = "V4fiiff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image2Dfi_ = struct {
+ const param_str = "V4fiiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image2Dif_ = struct {
+ const param_str = "V4iiiff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image2Dii_ = struct {
+ const param_str = "V4iiiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image3Dff_ = struct {
+ const param_str = "V4fiiffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image3Dfi_ = struct {
+ const param_str = "V4fiiiiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image3Dif_ = struct {
+ const param_str = "V4iiiffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_read_image3Dii_ = struct {
+ const param_str = "V4iiiiiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_write_image2Df_ = struct {
+ const param_str = "viiiffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_write_image2Di_ = struct {
+ const param_str = "viiiiiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_ptx_write_image2Dui_ = struct {
+ const param_str = "viiiUiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __builtin_r600_implicitarg_ptr = struct {
+ const param_str = "Uc*7";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_read_tgid_x = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_read_tgid_y = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_read_tgid_z = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_read_tidig_x = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_read_tidig_y = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_read_tidig_z = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_recipsqrt_ieee = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_r600_recipsqrt_ieeef = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .amdgpu = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_readcyclecounter = struct {
+ const param_str = "ULLi";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_readflm = struct {
+ const param_str = "d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_realloc = struct {
+ const param_str = "v*v*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_reduce_add = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_reduce_and = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_reduce_max = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_reduce_min = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_reduce_mul = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_reduce_or = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_reduce_xor = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_remainder = struct {
+ const param_str = "ddd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_remainderf = struct {
+ const param_str = "fff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_remainderf128 = struct {
+ const param_str = "LLdLLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_remainderl = struct {
+ const param_str = "LdLdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_remquo = struct {
+ const param_str = "dddi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_remquof = struct {
+ const param_str = "fffi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_remquof128 = struct {
+ const param_str = "LLdLLdLLdi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_remquol = struct {
+ const param_str = "LdLdLdi*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_return_address = struct {
+ const param_str = "v*IUi";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_rindex = struct {
+ const param_str = "c*cC*i";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_rint = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_rintf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_rintf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_rintf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_rintl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_rotateleft16 = struct {
+ const param_str = "UsUsUs";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_rotateleft32 = struct {
+ const param_str = "UZiUZiUZi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_rotateleft64 = struct {
+ const param_str = "UWiUWiUWi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_rotateleft8 = struct {
+ const param_str = "UcUcUc";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_rotateright16 = struct {
+ const param_str = "UsUsUs";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_rotateright32 = struct {
+ const param_str = "UZiUZiUZi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_rotateright64 = struct {
+ const param_str = "UWiUWiUWi";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_rotateright8 = struct {
+ const param_str = "UcUcUc";
+ const attributes = Attributes{
+ .@"const" = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_round = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_roundf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_roundf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_roundf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_roundl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_sadd_overflow = struct {
+ const param_str = "bSiCSiCSi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_saddl_overflow = struct {
+ const param_str = "bSLiCSLiCSLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_saddll_overflow = struct {
+ const param_str = "bSLLiCSLLiCSLLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_scalbln = struct {
+ const param_str = "ddLi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_scalblnf = struct {
+ const param_str = "ffLi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_scalblnf128 = struct {
+ const param_str = "LLdLLdLi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_scalblnl = struct {
+ const param_str = "LdLdLi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_scalbn = struct {
+ const param_str = "ddi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_scalbnf = struct {
+ const param_str = "ffi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_scalbnf128 = struct {
+ const param_str = "LLdLLdi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_scalbnl = struct {
+ const param_str = "LdLdi";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_set_texasr = struct {
+ const param_str = "vLUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_set_texasru = struct {
+ const param_str = "vLUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_set_tfhar = struct {
+ const param_str = "vLUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_set_tfiar = struct {
+ const param_str = "vLUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_setflm = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_setjmp = struct {
+ const param_str = "iv**";
+ const attributes = Attributes{
+ .returns_twice = true,
+ };
+ };
+
+ pub const __builtin_setps = struct {
+ const param_str = "vUiUi";
+ const target_set = TargetSet.init(.{
+ .xcore = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_setrnd = struct {
+ const param_str = "di";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_shufflevector = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_signbit = struct {
+ const param_str = "i.";
+ const attributes = Attributes{
+ .@"const" = true,
+ .custom_typecheck = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_signbitf = struct {
+ const param_str = "if";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_signbitl = struct {
+ const param_str = "iLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_sin = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinh = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinhf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinhf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinhl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sinl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_smul_overflow = struct {
+ const param_str = "bSiCSiCSi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_smull_overflow = struct {
+ const param_str = "bSLiCSLiCSLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_smulll_overflow = struct {
+ const param_str = "bSLLiCSLLiCSLLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_snprintf = struct {
+ const param_str = "ic*zcC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 2,
+ };
+ };
+
+ pub const __builtin_sponentry = struct {
+ const param_str = "v*";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_sprintf = struct {
+ const param_str = "ic*cC*.";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const __builtin_sqrt = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sqrtf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sqrtf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sqrtf128_round_to_odd = struct {
+ const param_str = "LLdLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_sqrtf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_sqrtl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_ssub_overflow = struct {
+ const param_str = "bSiCSiCSi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ssubl_overflow = struct {
+ const param_str = "bSLiCSLiCSLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_ssubll_overflow = struct {
+ const param_str = "bSLLiCSLLiCSLLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_stdarg_start = struct {
+ const param_str = "vA.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_stpcpy = struct {
+ const param_str = "c*c*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_stpncpy = struct {
+ const param_str = "c*c*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strcasecmp = struct {
+ const param_str = "icC*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strcat = struct {
+ const param_str = "c*c*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strchr = struct {
+ const param_str = "c*cC*i";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_strcmp = struct {
+ const param_str = "icC*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_strcpy = struct {
+ const param_str = "c*c*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strcspn = struct {
+ const param_str = "zcC*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strdup = struct {
+ const param_str = "c*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strlen = struct {
+ const param_str = "zcC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_strncasecmp = struct {
+ const param_str = "icC*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strncat = struct {
+ const param_str = "c*c*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strncmp = struct {
+ const param_str = "icC*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_strncpy = struct {
+ const param_str = "c*c*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strndup = struct {
+ const param_str = "c*cC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strpbrk = struct {
+ const param_str = "c*cC*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strrchr = struct {
+ const param_str = "c*cC*i";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strspn = struct {
+ const param_str = "zcC*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_strstr = struct {
+ const param_str = "c*cC*cC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_sub_overflow = struct {
+ const param_str = "b.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_subc = struct {
+ const param_str = "UiUiCUiCUiCUi*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_subcb = struct {
+ const param_str = "UcUcCUcCUcCUc*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_subcl = struct {
+ const param_str = "ULiULiCULiCULiCULi*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_subcll = struct {
+ const param_str = "ULLiULLiCULLiCULLiCULLi*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_subcs = struct {
+ const param_str = "UsUsCUsCUsCUs*";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_subf128_round_to_odd = struct {
+ const param_str = "LLdLLdLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tabort = struct {
+ const param_str = "UiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tabortdc = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tabortdci = struct {
+ const param_str = "UiUiUii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tabortwc = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tabortwci = struct {
+ const param_str = "UiUiUii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tan = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tanf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tanf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tanh = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tanhf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tanhf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tanhl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tanl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tbegin = struct {
+ const param_str = "UiUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tcheck = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tend = struct {
+ const param_str = "UiUIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tendall = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tgamma = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tgammaf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tgammaf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_tgammal = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __builtin_thread_pointer = struct {
+ const param_str = "v*";
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_trap = struct {
+ const param_str = "v";
+ const attributes = Attributes{
+ .noreturn = true,
+ };
+ };
+
+ pub const __builtin_trechkpt = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_treclaim = struct {
+ const param_str = "UiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tresume = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_trunc = struct {
+ const param_str = "dd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_truncf = struct {
+ const param_str = "ff";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_truncf128 = struct {
+ const param_str = "LLdLLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_truncf128_round_to_odd = struct {
+ const param_str = "dLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_truncf16 = struct {
+ const param_str = "hh";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_truncl = struct {
+ const param_str = "LdLd";
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_with_builtin_prefix = true,
+ };
+ };
+
+ pub const __builtin_tsr = struct {
+ const param_str = "UiUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_tsuspend = struct {
+ const param_str = "Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_ttest = struct {
+ const param_str = "LUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_uadd_overflow = struct {
+ const param_str = "bUiCUiCUi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_uaddl_overflow = struct {
+ const param_str = "bULiCULiCULi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_uaddll_overflow = struct {
+ const param_str = "bULLiCULLiCULLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_umul_overflow = struct {
+ const param_str = "bUiCUiCUi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_umull_overflow = struct {
+ const param_str = "bULiCULiCULi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_umulll_overflow = struct {
+ const param_str = "bULLiCULLiCULLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_unpack_longdouble = struct {
+ const param_str = "dLdIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_unpack_vector_int128 = struct {
+ const param_str = "ULLiV1LLLii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_unpredictable = struct {
+ const param_str = "LiLi";
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_unreachable = struct {
+ const param_str = "v";
+ const attributes = Attributes{
+ .noreturn = true,
+ };
+ };
+
+ pub const __builtin_unwind_init = struct {
+ const param_str = "v";
+ };
+
+ pub const __builtin_usub_overflow = struct {
+ const param_str = "bUiCUiCUi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_usubl_overflow = struct {
+ const param_str = "bULiCULiCULi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_usubll_overflow = struct {
+ const param_str = "bULLiCULLiCULLi*";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_va_copy = struct {
+ const param_str = "vAA";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_va_end = struct {
+ const param_str = "vA";
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_va_start = struct {
+ const param_str = "vA.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_ve_vl_andm_MMM = struct {
+ const param_str = "V512bV512bV512b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_andm_mmm = struct {
+ const param_str = "V256bV256bV256b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_eqvm_MMM = struct {
+ const param_str = "V512bV512bV512b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_eqvm_mmm = struct {
+ const param_str = "V256bV256bV256b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_extract_vm512l = struct {
+ const param_str = "V256bV512b";
+ const target_set = TargetSet.init(.{
+ .ve = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_extract_vm512u = struct {
+ const param_str = "V256bV512b";
+ const target_set = TargetSet.init(.{
+ .ve = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_fencec_s = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_fencei = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_fencem_s = struct {
+ const param_str = "vUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_fidcr_sss = struct {
+ const param_str = "LUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_insert_vm512l = struct {
+ const param_str = "V512bV512bV256b";
+ const target_set = TargetSet.init(.{
+ .ve = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_insert_vm512u = struct {
+ const param_str = "V512bV512bV256b";
+ const target_set = TargetSet.init(.{
+ .ve = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lcr_sss = struct {
+ const param_str = "LUiLUiLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lsv_vvss = struct {
+ const param_str = "V256dV256dUiLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lvm_MMss = struct {
+ const param_str = "V512bV512bLUiLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lvm_mmss = struct {
+ const param_str = "V256bV256bLUiLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lvsd_svs = struct {
+ const param_str = "dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lvsl_svs = struct {
+ const param_str = "LUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lvss_svs = struct {
+ const param_str = "fV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_lzvm_sml = struct {
+ const param_str = "LUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_negm_MM = struct {
+ const param_str = "V512bV512b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_negm_mm = struct {
+ const param_str = "V256bV256b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_nndm_MMM = struct {
+ const param_str = "V512bV512bV512b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_nndm_mmm = struct {
+ const param_str = "V256bV256bV256b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_orm_MMM = struct {
+ const param_str = "V512bV512bV512b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_orm_mmm = struct {
+ const param_str = "V256bV256bV256b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pack_f32a = struct {
+ const param_str = "ULifC*";
+ const target_set = TargetSet.init(.{
+ .ve = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pack_f32p = struct {
+ const param_str = "ULifC*fC*";
+ const target_set = TargetSet.init(.{
+ .ve = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pcvm_sml = struct {
+ const param_str = "LUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pfchv_ssl = struct {
+ const param_str = "vLivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pfchvnc_ssl = struct {
+ const param_str = "vLivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvadds_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvadds_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvadds_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvadds_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvadds_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvadds_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvaddu_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvaddu_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvaddu_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvaddu_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvaddu_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvaddu_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvand_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvand_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvand_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvand_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvand_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvand_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrd_vsMvl = struct {
+ const param_str = "V256dLUiV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrd_vsl = struct {
+ const param_str = "V256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrd_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrv_vvMvl = struct {
+ const param_str = "V256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrv_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrv_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrvlo_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrvlo_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrvlo_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrvup_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrvup_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvbrvup_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmps_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmps_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmps_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmps_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmps_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmps_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmpu_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmpu_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmpu_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmpu_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmpu_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcmpu_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtsw_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtsw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtws_vvMvl = struct {
+ const param_str = "V256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtws_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtws_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtwsrz_vvMvl = struct {
+ const param_str = "V256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtwsrz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvcvtwsrz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pveqv_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pveqv_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pveqv_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pveqv_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pveqv_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pveqv_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfadd_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfadd_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfadd_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfadd_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfadd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfadd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfcmp_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfcmp_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfcmp_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfcmp_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfcmp_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfcmp_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vsvvMvl = struct {
+ const param_str = "V256dLUiV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vsvvvl = struct {
+ const param_str = "V256dLUiV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vvsvMvl = struct {
+ const param_str = "V256dV256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vvsvvl = struct {
+ const param_str = "V256dV256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vvvvMvl = struct {
+ const param_str = "V256dV256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmad_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmax_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmax_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmax_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmax_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmax_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmax_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmin_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmin_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmin_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmin_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmin_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmin_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkaf_Ml = struct {
+ const param_str = "V512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkat_Ml = struct {
+ const param_str = "V512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkseq_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkseq_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkseqnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkseqnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksge_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksge_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksgenan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksgenan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksgt_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksgt_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksgtnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksgtnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksle_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksle_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslenan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslenan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloeq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloeq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloeqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloeqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslogenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslogenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslogt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslogt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslogtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslogtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslole_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslole_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslolenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslolenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslolt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslolt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksloltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslonan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslonan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslone_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslone_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslonenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslonenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslonum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslonum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslt_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkslt_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksltnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksltnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksne_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksne_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksnenan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksnenan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksnum_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksnum_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupeq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupeq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupeqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupeqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupgenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupgenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupgt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupgt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupgtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupgtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksuple_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksuple_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksuplenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksuplenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksuplt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksuplt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupne_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupne_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupnenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupnenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupnum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmksupnum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkweq_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkweq_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkweqnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkweqnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwge_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwge_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwgenan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwgenan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwgt_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwgt_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwgtnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwgtnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwle_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwle_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlenan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlenan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloeq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloeq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloeqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloeqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlogenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlogenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlogt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlogt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlogtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlogtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlole_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlole_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlolenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlolenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlolt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlolt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwloltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlonan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlonan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlone_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlone_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlonenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlonenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlonum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlonum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlt_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwlt_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwltnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwltnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwnan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwnan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwne_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwne_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwnenan_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwnenan_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwnum_MvMl = struct {
+ const param_str = "V512bV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwnum_Mvl = struct {
+ const param_str = "V512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupeq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupeq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupeqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupeqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupgenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupgenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupgt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupgt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupgtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupgtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwuple_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwuple_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwuplenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwuplenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwuplt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwuplt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupne_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupne_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupnenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupnenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupnum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmkwupnum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vsvvMvl = struct {
+ const param_str = "V256dLUiV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vsvvvl = struct {
+ const param_str = "V256dLUiV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vvsvMvl = struct {
+ const param_str = "V256dV256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vvsvvl = struct {
+ const param_str = "V256dV256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vvvvMvl = struct {
+ const param_str = "V256dV256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmsb_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmul_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmul_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmul_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmul_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmul_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfmul_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vsvvMvl = struct {
+ const param_str = "V256dLUiV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vsvvvl = struct {
+ const param_str = "V256dLUiV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vvsvMvl = struct {
+ const param_str = "V256dV256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vvsvvl = struct {
+ const param_str = "V256dV256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vvvvMvl = struct {
+ const param_str = "V256dV256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmad_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vsvvMvl = struct {
+ const param_str = "V256dLUiV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vsvvvl = struct {
+ const param_str = "V256dLUiV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vvsvMvl = struct {
+ const param_str = "V256dV256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vvsvvl = struct {
+ const param_str = "V256dV256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vvvvMvl = struct {
+ const param_str = "V256dV256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfnmsb_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfsub_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfsub_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfsub_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfsub_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfsub_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvfsub_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldz_vvMvl = struct {
+ const param_str = "V256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldzlo_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldzlo_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldzlo_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldzup_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldzup_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvldzup_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmaxs_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmaxs_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmaxs_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmaxs_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmaxs_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmaxs_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmins_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmins_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmins_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmins_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmins_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvmins_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvor_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvor_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvor_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvor_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvor_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvor_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcnt_vvMvl = struct {
+ const param_str = "V256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcnt_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcnt_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcntlo_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcntlo_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcntlo_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcntup_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcntup_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvpcntup_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvrcp_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvrcp_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvrsqrt_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvrsqrt_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvrsqrtnex_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvrsqrtnex_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvseq_vl = struct {
+ const param_str = "V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvseq_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvseqlo_vl = struct {
+ const param_str = "V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvseqlo_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsequp_vl = struct {
+ const param_str = "V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsequp_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsla_vvsMvl = struct {
+ const param_str = "V256dV256dLUiV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsla_vvsl = struct {
+ const param_str = "V256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsla_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsla_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsla_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsla_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsll_vvsMvl = struct {
+ const param_str = "V256dV256dLUiV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsll_vvsl = struct {
+ const param_str = "V256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsll_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsll_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsll_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsll_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsra_vvsMvl = struct {
+ const param_str = "V256dV256dLUiV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsra_vvsl = struct {
+ const param_str = "V256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsra_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsra_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsra_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsra_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsrl_vvsMvl = struct {
+ const param_str = "V256dV256dLUiV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsrl_vvsl = struct {
+ const param_str = "V256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsrl_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsrl_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsrl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsrl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubs_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubs_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubs_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubs_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubs_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubs_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubu_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubu_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubu_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubu_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubu_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvsubu_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvxor_vsvMvl = struct {
+ const param_str = "V256dLUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvxor_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvxor_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvxor_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvxor_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_pvxor_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_scr_sss = struct {
+ const param_str = "vLUiLUiLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_svm_sMs = struct {
+ const param_str = "LUiV512bLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_svm_sms = struct {
+ const param_str = "LUiV256bLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_svob = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_tovm_sml = struct {
+ const param_str = "LUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_tscr_ssss = struct {
+ const param_str = "LUiLUiLUiLUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddsl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddsl_vsvmvl = struct {
+ const param_str = "V256dLiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddsl_vsvvl = struct {
+ const param_str = "V256dLiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddsl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddsl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddsl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswsx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswsx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswsx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswzx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswzx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswzx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddswzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddul_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddul_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddul_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddul_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddul_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vaddul_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vadduw_vsvl = struct {
+ const param_str = "V256dUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vadduw_vsvmvl = struct {
+ const param_str = "V256dUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vadduw_vsvvl = struct {
+ const param_str = "V256dUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vadduw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vadduw_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vadduw_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vand_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vand_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vand_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vand_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vand_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vand_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdd_vsl = struct {
+ const param_str = "V256ddUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdd_vsmvl = struct {
+ const param_str = "V256ddV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdd_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdl_vsl = struct {
+ const param_str = "V256dLiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdl_vsmvl = struct {
+ const param_str = "V256dLiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrds_vsl = struct {
+ const param_str = "V256dfUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrds_vsmvl = struct {
+ const param_str = "V256dfV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrds_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdw_vsl = struct {
+ const param_str = "V256diUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdw_vsmvl = struct {
+ const param_str = "V256diV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrdw_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrv_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrv_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vbrv_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpsl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpsl_vsvmvl = struct {
+ const param_str = "V256dLiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpsl_vsvvl = struct {
+ const param_str = "V256dLiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpsl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpsl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpsl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswsx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswsx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswsx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswzx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswzx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswzx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpswzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpul_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpul_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpul_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpul_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpul_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpul_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpuw_vsvl = struct {
+ const param_str = "V256dUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpuw_vsvmvl = struct {
+ const param_str = "V256dUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpuw_vsvvl = struct {
+ const param_str = "V256dUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpuw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpuw_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcmpuw_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcp_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtdl_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtdl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtds_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtds_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtdw_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtdw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtld_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtld_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtld_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtldrz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtldrz_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtldrz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtsd_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtsd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtsw_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtsw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdsx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdsx_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdsxrz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdsxrz_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdsxrz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdzx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdzx_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdzxrz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdzxrz_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwdzxrz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwssx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwssx_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwssx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwssxrz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwssxrz_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwssxrz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwszx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwszx_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwszx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwszxrz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwszxrz_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vcvtwszxrz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vsvmvl = struct {
+ const param_str = "V256dLiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vsvvl = struct {
+ const param_str = "V256dLiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vvsl = struct {
+ const param_str = "V256dV256dLiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vvsmvl = struct {
+ const param_str = "V256dV256dLiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vvsvl = struct {
+ const param_str = "V256dV256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivsl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vvsl = struct {
+ const param_str = "V256dV256diUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vvsmvl = struct {
+ const param_str = "V256dV256diV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vvsvl = struct {
+ const param_str = "V256dV256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vvsl = struct {
+ const param_str = "V256dV256diUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vvsmvl = struct {
+ const param_str = "V256dV256diV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vvsvl = struct {
+ const param_str = "V256dV256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivswzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vvsl = struct {
+ const param_str = "V256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vvsmvl = struct {
+ const param_str = "V256dV256dLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivul_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vsvl = struct {
+ const param_str = "V256dUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vsvmvl = struct {
+ const param_str = "V256dUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vsvvl = struct {
+ const param_str = "V256dUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vvsl = struct {
+ const param_str = "V256dV256dUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vvsmvl = struct {
+ const param_str = "V256dV256dUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vvsvl = struct {
+ const param_str = "V256dV256dUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vdivuw_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_veqv_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_veqv_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_veqv_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_veqv_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_veqv_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_veqv_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vex_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfaddd_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfaddd_vsvmvl = struct {
+ const param_str = "V256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfaddd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfaddd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfaddd_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfaddd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfadds_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfadds_vsvmvl = struct {
+ const param_str = "V256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfadds_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfadds_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfadds_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfadds_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmpd_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmpd_vsvmvl = struct {
+ const param_str = "V256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmpd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmpd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmpd_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmpd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmps_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmps_vsvmvl = struct {
+ const param_str = "V256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmps_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmps_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmps_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfcmps_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivd_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivd_vsvmvl = struct {
+ const param_str = "V256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivd_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivs_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivs_vsvmvl = struct {
+ const param_str = "V256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivs_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivs_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivs_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfdivs_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vsvvmvl = struct {
+ const param_str = "V256ddV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vsvvvl = struct {
+ const param_str = "V256ddV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vvsvl = struct {
+ const param_str = "V256dV256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vvsvmvl = struct {
+ const param_str = "V256dV256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vvsvvl = struct {
+ const param_str = "V256dV256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmadd_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vsvvmvl = struct {
+ const param_str = "V256dfV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vsvvvl = struct {
+ const param_str = "V256dfV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vvsvl = struct {
+ const param_str = "V256dV256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vvsvmvl = struct {
+ const param_str = "V256dV256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vvsvvl = struct {
+ const param_str = "V256dV256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmads_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxd_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxd_vsvmvl = struct {
+ const param_str = "V256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxd_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxs_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxs_vsvmvl = struct {
+ const param_str = "V256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxs_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxs_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxs_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmaxs_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmind_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmind_vsvmvl = struct {
+ const param_str = "V256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmind_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmind_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmind_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmind_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmins_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmins_vsvmvl = struct {
+ const param_str = "V256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmins_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmins_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmins_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmins_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdeq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdeq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdeqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdeqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdgenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdgenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdgt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdgt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdgtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdgtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdle_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdle_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdlenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdlenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdlt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdlt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdne_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdne_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdnenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdnenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdnum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkdnum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklaf_ml = struct {
+ const param_str = "V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklat_ml = struct {
+ const param_str = "V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkleq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkleq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkleqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkleqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklgenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklgenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklgt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklgt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklgtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklgtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklle_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklle_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkllenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkllenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkllt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkllt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklne_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklne_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklnenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklnenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklnum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmklnum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkseq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkseq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkseqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkseqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksgenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksgenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksgt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksgt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksgtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksgtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksle_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksle_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkslenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkslenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkslt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkslt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksne_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksne_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksnenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksnenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksnum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmksnum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkweq_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkweq_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkweqnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkweqnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwge_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwge_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwgenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwgenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwgt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwgt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwgtnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwgtnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwle_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwle_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwlenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwlenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwlt_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwlt_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwltnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwltnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwnan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwnan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwne_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwne_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwnenan_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwnenan_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwnum_mvl = struct {
+ const param_str = "V256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmkwnum_mvml = struct {
+ const param_str = "V256bV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vsvvmvl = struct {
+ const param_str = "V256ddV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vsvvvl = struct {
+ const param_str = "V256ddV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vvsvl = struct {
+ const param_str = "V256dV256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vvsvmvl = struct {
+ const param_str = "V256dV256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vvsvvl = struct {
+ const param_str = "V256dV256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbd_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vsvvmvl = struct {
+ const param_str = "V256dfV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vsvvvl = struct {
+ const param_str = "V256dfV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vvsvl = struct {
+ const param_str = "V256dV256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vvsvmvl = struct {
+ const param_str = "V256dV256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vvsvvl = struct {
+ const param_str = "V256dV256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmsbs_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuld_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuld_vsvmvl = struct {
+ const param_str = "V256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuld_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuld_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuld_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuld_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuls_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuls_vsvmvl = struct {
+ const param_str = "V256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuls_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuls_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuls_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfmuls_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vsvvmvl = struct {
+ const param_str = "V256ddV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vsvvvl = struct {
+ const param_str = "V256ddV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vvsvl = struct {
+ const param_str = "V256dV256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vvsvmvl = struct {
+ const param_str = "V256dV256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vvsvvl = struct {
+ const param_str = "V256dV256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmadd_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vsvvmvl = struct {
+ const param_str = "V256dfV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vsvvvl = struct {
+ const param_str = "V256dfV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vvsvl = struct {
+ const param_str = "V256dV256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vvsvmvl = struct {
+ const param_str = "V256dV256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vvsvvl = struct {
+ const param_str = "V256dV256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmads_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vsvvmvl = struct {
+ const param_str = "V256ddV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vsvvvl = struct {
+ const param_str = "V256ddV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vvsvl = struct {
+ const param_str = "V256dV256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vvsvmvl = struct {
+ const param_str = "V256dV256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vvsvvl = struct {
+ const param_str = "V256dV256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbd_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vsvvmvl = struct {
+ const param_str = "V256dfV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vsvvvl = struct {
+ const param_str = "V256dfV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vvsvl = struct {
+ const param_str = "V256dV256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vvsvmvl = struct {
+ const param_str = "V256dV256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vvsvvl = struct {
+ const param_str = "V256dV256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vvvvmvl = struct {
+ const param_str = "V256dV256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfnmsbs_vvvvvl = struct {
+ const param_str = "V256dV256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxdfst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxdfst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxdlst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxdlst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxsfst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxsfst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxslst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmaxslst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmindfst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmindfst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmindlst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrmindlst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrminsfst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrminsfst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrminslst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfrminslst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsqrtd_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsqrtd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsqrts_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsqrts_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubd_vsvl = struct {
+ const param_str = "V256ddV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubd_vsvmvl = struct {
+ const param_str = "V256ddV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubd_vsvvl = struct {
+ const param_str = "V256ddV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubd_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubd_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubs_vsvl = struct {
+ const param_str = "V256dfV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubs_vsvmvl = struct {
+ const param_str = "V256dfV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubs_vsvvl = struct {
+ const param_str = "V256dfV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubs_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubs_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsubs_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsumd_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsumd_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsums_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vfsums_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgt_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgt_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgt_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgt_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsx_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsx_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsx_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsx_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsxnc_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsxnc_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsxnc_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlsxnc_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzx_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzx_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzx_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzx_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzxnc_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzxnc_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzxnc_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtlzxnc_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtnc_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtnc_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtnc_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtnc_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtu_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtu_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtu_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtu_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtunc_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtunc_vvssml = struct {
+ const param_str = "V256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtunc_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vgtunc_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vld2d_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vld2d_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vld2dnc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vld2dnc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vld_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vld_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dsx_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dsx_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dsxnc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dsxnc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dzx_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dzx_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dzxnc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldl2dzxnc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlsx_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlsx_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlsxnc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlsxnc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlzx_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlzx_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlzxnc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldlzxnc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldnc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldnc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldu2d_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldu2d_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldu2dnc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldu2dnc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldu_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldu_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldunc_vssl = struct {
+ const param_str = "V256dLUivC*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldunc_vssvl = struct {
+ const param_str = "V256dLUivC*V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldz_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldz_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vldz_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxsl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxsl_vsvmvl = struct {
+ const param_str = "V256dLiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxsl_vsvvl = struct {
+ const param_str = "V256dLiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxsl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxsl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxsl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswsx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswsx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswsx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswzx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswzx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswzx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmaxswzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminsl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminsl_vsvmvl = struct {
+ const param_str = "V256dLiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminsl_vsvvl = struct {
+ const param_str = "V256dLiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminsl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminsl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminsl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswsx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswsx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswsx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswzx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswzx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswzx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vminswzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrg_vsvml = struct {
+ const param_str = "V256dLUiV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrg_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrg_vvvml = struct {
+ const param_str = "V256dV256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrg_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrgw_vsvMl = struct {
+ const param_str = "V256dUiV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrgw_vsvMvl = struct {
+ const param_str = "V256dUiV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrgw_vvvMl = struct {
+ const param_str = "V256dV256dV256dV512bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmrgw_vvvMvl = struct {
+ const param_str = "V256dV256dV256dV512bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulsl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulsl_vsvmvl = struct {
+ const param_str = "V256dLiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulsl_vsvvl = struct {
+ const param_str = "V256dLiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulsl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulsl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulsl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulslw_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulslw_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulslw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulslw_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswsx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswsx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswsx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswzx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswzx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswzx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulswzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulul_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulul_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulul_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulul_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulul_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmulul_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmuluw_vsvl = struct {
+ const param_str = "V256dUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmuluw_vsvmvl = struct {
+ const param_str = "V256dUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmuluw_vsvvl = struct {
+ const param_str = "V256dUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmuluw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmuluw_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmuluw_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmv_vsvl = struct {
+ const param_str = "V256dUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmv_vsvmvl = struct {
+ const param_str = "V256dUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vmv_vsvvl = struct {
+ const param_str = "V256dUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vor_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vor_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vor_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vor_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vor_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vor_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vpcnt_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vpcnt_vvmvl = struct {
+ const param_str = "V256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vpcnt_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrand_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrand_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrcpd_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrcpd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrcps_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrcps_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxslfst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxslfst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxsllst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxsllst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswfstsx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswfstsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswfstzx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswfstzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswlstsx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswlstsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswlstzx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrmaxswlstzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminslfst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminslfst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminsllst_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminsllst_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswfstsx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswfstsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswfstzx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswfstzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswlstsx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswlstsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswlstzx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrminswlstzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vror_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vror_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrtd_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrtd_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrtdnex_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrtdnex_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrts_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrts_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrtsnex_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrsqrtsnex_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrxor_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vrxor_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsc_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsc_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscl_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscl_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsclnc_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsclnc_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsclncot_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsclncot_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsclot_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsclot_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscnc_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscnc_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscncot_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscncot_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscot_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscot_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscu_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscu_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscunc_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscunc_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscuncot_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscuncot_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscuot_vvssl = struct {
+ const param_str = "vV256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vscuot_vvssml = struct {
+ const param_str = "vV256dV256dLUiLUiV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vseq_vl = struct {
+ const param_str = "V256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vseq_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsfa_vvssl = struct {
+ const param_str = "V256dV256dLUiLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsfa_vvssmvl = struct {
+ const param_str = "V256dV256dLUiLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsfa_vvssvl = struct {
+ const param_str = "V256dV256dLUiLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vshf_vvvsl = struct {
+ const param_str = "V256dV256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vshf_vvvsvl = struct {
+ const param_str = "V256dV256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslal_vvsl = struct {
+ const param_str = "V256dV256dLiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslal_vvsmvl = struct {
+ const param_str = "V256dV256dLiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslal_vvsvl = struct {
+ const param_str = "V256dV256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslal_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslal_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslal_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawsx_vvsl = struct {
+ const param_str = "V256dV256diUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawsx_vvsmvl = struct {
+ const param_str = "V256dV256diV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawsx_vvsvl = struct {
+ const param_str = "V256dV256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawzx_vvsl = struct {
+ const param_str = "V256dV256diUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawzx_vvsmvl = struct {
+ const param_str = "V256dV256diV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawzx_vvsvl = struct {
+ const param_str = "V256dV256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vslawzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsll_vvsl = struct {
+ const param_str = "V256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsll_vvsmvl = struct {
+ const param_str = "V256dV256dLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsll_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsll_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsll_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsll_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsral_vvsl = struct {
+ const param_str = "V256dV256dLiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsral_vvsmvl = struct {
+ const param_str = "V256dV256dLiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsral_vvsvl = struct {
+ const param_str = "V256dV256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsral_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsral_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsral_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawsx_vvsl = struct {
+ const param_str = "V256dV256diUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawsx_vvsmvl = struct {
+ const param_str = "V256dV256diV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawsx_vvsvl = struct {
+ const param_str = "V256dV256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawzx_vvsl = struct {
+ const param_str = "V256dV256diUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawzx_vvsmvl = struct {
+ const param_str = "V256dV256diV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawzx_vvsvl = struct {
+ const param_str = "V256dV256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrawzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrl_vvsl = struct {
+ const param_str = "V256dV256dLUiUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrl_vvsmvl = struct {
+ const param_str = "V256dV256dLUiV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrl_vvsvl = struct {
+ const param_str = "V256dV256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsrl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2d_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2d_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2dnc_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2dnc_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2dncot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2dncot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2dot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst2dot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vst_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2d_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2d_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2dnc_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2dnc_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2dncot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2dncot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2dot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl2dot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstl_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstlnc_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstlnc_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstlncot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstlncot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstlot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstlot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstnc_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstnc_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstncot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstncot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2d_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2d_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2dnc_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2dnc_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2dncot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2dncot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2dot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu2dot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstu_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstunc_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstunc_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstuncot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstuncot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstuot_vssl = struct {
+ const param_str = "vV256dLUiv*Ui";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vstuot_vssml = struct {
+ const param_str = "vV256dLUiv*V256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubsl_vsvl = struct {
+ const param_str = "V256dLiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubsl_vsvmvl = struct {
+ const param_str = "V256dLiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubsl_vsvvl = struct {
+ const param_str = "V256dLiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubsl_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubsl_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubsl_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswsx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswsx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswsx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswsx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswsx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswsx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswzx_vsvl = struct {
+ const param_str = "V256diV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswzx_vsvmvl = struct {
+ const param_str = "V256diV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswzx_vsvvl = struct {
+ const param_str = "V256diV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswzx_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswzx_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubswzx_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubul_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubul_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubul_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubul_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubul_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubul_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubuw_vsvl = struct {
+ const param_str = "V256dUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubuw_vsvmvl = struct {
+ const param_str = "V256dUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubuw_vsvvl = struct {
+ const param_str = "V256dUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubuw_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubuw_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsubuw_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsuml_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsuml_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsumwsx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsumwsx_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsumwzx_vvl = struct {
+ const param_str = "V256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vsumwzx_vvml = struct {
+ const param_str = "V256dV256dV256bUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vxor_vsvl = struct {
+ const param_str = "V256dLUiV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vxor_vsvmvl = struct {
+ const param_str = "V256dLUiV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vxor_vsvvl = struct {
+ const param_str = "V256dLUiV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vxor_vvvl = struct {
+ const param_str = "V256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vxor_vvvmvl = struct {
+ const param_str = "V256dV256dV256dV256bV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_vxor_vvvvl = struct {
+ const param_str = "V256dV256dV256dV256dUi";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_xorm_MMM = struct {
+ const param_str = "V512bV512bV512b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_ve_vl_xorm_mmm = struct {
+ const param_str = "V256bV256bV256b";
+ const target_set = TargetSet.init(.{
+ .vevl_gen = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_vsnprintf = struct {
+ const param_str = "ic*zcC*a";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 2,
+ };
+ };
+
+ pub const __builtin_vsprintf = struct {
+ const param_str = "ic*cC*a";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const __builtin_vsx_extractuword = struct {
+ const param_str = "V2ULLiV16UcIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_insertword = struct {
+ const param_str = "V16UcV4UiV16UcIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_ldrmb = struct {
+ const param_str = "V16UcCc*Ii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_lxvd2x = struct {
+ const param_str = "V2dLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_lxvd2x_be = struct {
+ const param_str = "V2dSLLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_lxvl = struct {
+ const param_str = "V4ivC*ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_lxvll = struct {
+ const param_str = "V4ivC*ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_lxvw4x = struct {
+ const param_str = "V4iLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_lxvw4x_be = struct {
+ const param_str = "V4iSLLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_scalar_extract_expq = struct {
+ const param_str = "ULLiLLd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_scalar_insert_exp_qp = struct {
+ const param_str = "LLdLLdULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_strmb = struct {
+ const param_str = "vCc*IiV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_stxvd2x = struct {
+ const param_str = "vV2dLiv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_stxvd2x_be = struct {
+ const param_str = "vV2dSLLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_stxvl = struct {
+ const param_str = "vV4iv*ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_stxvll = struct {
+ const param_str = "vV4iv*ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_stxvw4x = struct {
+ const param_str = "vV4iLiv*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_stxvw4x_be = struct {
+ const param_str = "vV4iSLLivC*";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xsmaxdp = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xsmindp = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvabsdp = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvabssp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpeqdp = struct {
+ const param_str = "V2ULLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpeqdp_p = struct {
+ const param_str = "iiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpeqsp = struct {
+ const param_str = "V4UiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpeqsp_p = struct {
+ const param_str = "iiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgedp = struct {
+ const param_str = "V2ULLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgedp_p = struct {
+ const param_str = "iiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgesp = struct {
+ const param_str = "V4UiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgesp_p = struct {
+ const param_str = "iiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgtdp = struct {
+ const param_str = "V2ULLiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgtdp_p = struct {
+ const param_str = "iiV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgtsp = struct {
+ const param_str = "V4UiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcmpgtsp_p = struct {
+ const param_str = "iiV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcpsgndp = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcpsgnsp = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvbf16spn = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvdpsp = struct {
+ const param_str = "V4fV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvdpsxws = struct {
+ const param_str = "V4SiV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvdpuxws = struct {
+ const param_str = "V4UiV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvhpsp = struct {
+ const param_str = "V4fV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvspbf16 = struct {
+ const param_str = "V16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvspdp = struct {
+ const param_str = "V2dV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvsphp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvspsxds = struct {
+ const param_str = "V2SLLiV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvspuxds = struct {
+ const param_str = "V2ULLiV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvsxdsp = struct {
+ const param_str = "V4fV2SLLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvsxwdp = struct {
+ const param_str = "V2dV4Si";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvuxdsp = struct {
+ const param_str = "V4fV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvcvuxwdp = struct {
+ const param_str = "V2dV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvdivdp = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvdivsp = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xviexpdp = struct {
+ const param_str = "V2dV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xviexpsp = struct {
+ const param_str = "V4fV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmaddadp = struct {
+ const param_str = "V2dV2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmaddasp = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmaxdp = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmaxsp = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmindp = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvminsp = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmsubadp = struct {
+ const param_str = "V2dV2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmsubasp = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmuldp = struct {
+ const param_str = "V2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvmulsp = struct {
+ const param_str = "V4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvnmaddadp = struct {
+ const param_str = "V2dV2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvnmaddasp = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvnmsubadp = struct {
+ const param_str = "V2dV2dV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvnmsubasp = struct {
+ const param_str = "V4fV4fV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrdpi = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrdpic = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrdpim = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrdpip = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrdpiz = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvredp = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvresp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrspi = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrspic = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrspim = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrspip = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrspiz = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrsqrtedp = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvrsqrtesp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvsqrtdp = struct {
+ const param_str = "V2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvsqrtsp = struct {
+ const param_str = "V4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvtdivdp = struct {
+ const param_str = "iV2dV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvtdivsp = struct {
+ const param_str = "iV4fV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvtlsbb = struct {
+ const param_str = "iV16UcUi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvtsqrtdp = struct {
+ const param_str = "iV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvtsqrtsp = struct {
+ const param_str = "iV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvtstdcdp = struct {
+ const param_str = "V2ULLiV2dIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvtstdcsp = struct {
+ const param_str = "V4UiV4fIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvxexpdp = struct {
+ const param_str = "V2ULLiV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvxexpsp = struct {
+ const param_str = "V4UiV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvxsigdp = struct {
+ const param_str = "V2ULLiV2d";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xvxsigsp = struct {
+ const param_str = "V4UiV4f";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxblendvb = struct {
+ const param_str = "V16UcV16UcV16UcV16Uc";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxblendvd = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxblendvh = struct {
+ const param_str = "V8UsV8UsV8UsV8Us";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxblendvw = struct {
+ const param_str = "V4UiV4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxeval = struct {
+ const param_str = "V2ULLiV2ULLiV2ULLiV2ULLiIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxgenpcvbm = struct {
+ const param_str = "V16UcV16Uci";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxgenpcvdm = struct {
+ const param_str = "V2ULLiV2ULLii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxgenpcvhm = struct {
+ const param_str = "V8UsV8Usi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxgenpcvwm = struct {
+ const param_str = "V4UiV4Uii";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxleqv = struct {
+ const param_str = "V4UiV4UiV4Ui";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxpermdi = struct {
+ const param_str = "v.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_vsx_xxpermx = struct {
+ const param_str = "V16UcV16UcV16UcV16UcIi";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ };
+
+ pub const __builtin_vsx_xxsldwi = struct {
+ const param_str = "v.";
+ const target_set = TargetSet.init(.{
+ .ppc = true,
+ });
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __builtin_wasm_max_f32 = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_max_f64 = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_memory_grow = struct {
+ const param_str = "zIiz";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_wasm_memory_size = struct {
+ const param_str = "zIi";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __builtin_wasm_min_f32 = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_min_f64 = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_s_i32_f32 = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_s_i32_f64 = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_s_i64_f32 = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_s_i64_f64 = struct {
+ const param_str = "LLid";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_u_i32_f32 = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_u_i32_f64 = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_u_i64_f32 = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wasm_trunc_u_i64_f64 = struct {
+ const param_str = "LLid";
+ const target_set = TargetSet.init(.{
+ .webassembly = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __builtin_wcschr = struct {
+ const param_str = "w*wC*w";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_wcscmp = struct {
+ const param_str = "iwC*wC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_wcslen = struct {
+ const param_str = "zwC*";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_wcsncmp = struct {
+ const param_str = "iwC*wC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_wmemchr = struct {
+ const param_str = "w*wC*wz";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_wmemcmp = struct {
+ const param_str = "iwC*wC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_wmemcpy = struct {
+ const param_str = "w*w*wC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __builtin_wmemmove = struct {
+ const param_str = "w*w*wC*z";
+ const attributes = Attributes{
+ .lib_function_with_builtin_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __c11_atomic_is_lock_free = struct {
+ const param_str = "bz";
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const __c11_atomic_signal_fence = struct {
+ const param_str = "vi";
+ const attributes = Attributes{};
+ };
+
+ pub const __c11_atomic_thread_fence = struct {
+ const param_str = "vi";
+ const attributes = Attributes{};
+ };
+
+ pub const __clear_cache = struct {
+ const param_str = "vv*v*";
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __cospi = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __cospif = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __debugbreak = struct {
+ const param_str = "v";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __dmb = struct {
+ const param_str = "vUi";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __dsb = struct {
+ const param_str = "vUi";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __emit = struct {
+ const param_str = "vIUiC";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __exception_code = struct {
+ const param_str = "UNi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __exception_info = struct {
+ const param_str = "v*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __exp10 = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __exp10f = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __fastfail = struct {
+ const param_str = "vUi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .noreturn = true,
+ };
+ };
+
+ pub const __finite = struct {
+ const param_str = "id";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const __finitef = struct {
+ const param_str = "if";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const __finitel = struct {
+ const param_str = "iLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const __isb = struct {
+ const param_str = "vUi";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __iso_volatile_load16 = struct {
+ const param_str = "ssCD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __iso_volatile_load32 = struct {
+ const param_str = "iiCD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __iso_volatile_load64 = struct {
+ const param_str = "LLiLLiCD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __iso_volatile_load8 = struct {
+ const param_str = "ccCD*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __iso_volatile_store16 = struct {
+ const param_str = "vsD*s";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __iso_volatile_store32 = struct {
+ const param_str = "viD*i";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __iso_volatile_store64 = struct {
+ const param_str = "vLLiD*LLi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __iso_volatile_store8 = struct {
+ const param_str = "vcD*c";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __ldrexd = struct {
+ const param_str = "WiWiCD*";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .arm = true,
+ });
+ };
+
+ pub const __lzcnt = struct {
+ const param_str = "UiUi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __lzcnt16 = struct {
+ const param_str = "UsUs";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __lzcnt64 = struct {
+ const param_str = "UWiUWi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __noop = struct {
+ const param_str = "i.";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_add_rm_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rm_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rm_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rn_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rn_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rn_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rp_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rp_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rp_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rz_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_add_rz_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_atom_add_gen_f = struct {
+ const param_str = "ffD*f";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_add_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_add_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_add_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_and_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_and_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_and_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_cas_gen_i = struct {
+ const param_str = "iiD*ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_cas_gen_l = struct {
+ const param_str = "LiLiD*LiLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_cas_gen_ll = struct {
+ const param_str = "LLiLLiD*LLiLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_dec_gen_ui = struct {
+ const param_str = "UiUiD*Ui";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_inc_gen_ui = struct {
+ const param_str = "UiUiD*Ui";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_max_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_max_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_max_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_max_gen_ui = struct {
+ const param_str = "UiUiD*Ui";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_max_gen_ul = struct {
+ const param_str = "ULiULiD*ULi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_max_gen_ull = struct {
+ const param_str = "ULLiULLiD*ULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_min_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_min_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_min_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_min_gen_ui = struct {
+ const param_str = "UiUiD*Ui";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_min_gen_ul = struct {
+ const param_str = "ULiULiD*ULi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_min_gen_ull = struct {
+ const param_str = "ULLiULLiD*ULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_or_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_or_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_or_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_sub_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_sub_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_sub_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_xchg_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_xchg_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_xchg_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_xor_gen_i = struct {
+ const param_str = "iiD*i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_xor_gen_l = struct {
+ const param_str = "LiLiD*Li";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_atom_xor_gen_ll = struct {
+ const param_str = "LLiLLiD*LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_bar0_and = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_bar0_or = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_bar0_popc = struct {
+ const param_str = "ii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_bar_sync = struct {
+ const param_str = "vi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_bitcast_d2ll = struct {
+ const param_str = "LLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_bitcast_f2i = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_bitcast_i2f = struct {
+ const param_str = "fi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_bitcast_ll2d = struct {
+ const param_str = "dLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ceil_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ceil_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ceil_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_compiler_error = struct {
+ const param_str = "vcC*4";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_compiler_warn = struct {
+ const param_str = "vcC*4";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_cos_approx_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_cos_approx_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rm = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rm_ftz = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rn = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rn_ftz = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rp = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rp_ftz = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rz = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2f_rz_ftz = struct {
+ const param_str = "fd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2i_hi = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2i_lo = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2i_rm = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2i_rn = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2i_rp = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2i_rz = struct {
+ const param_str = "id";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ll_rm = struct {
+ const param_str = "LLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ll_rn = struct {
+ const param_str = "LLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ll_rp = struct {
+ const param_str = "LLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ll_rz = struct {
+ const param_str = "LLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ui_rm = struct {
+ const param_str = "Uid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ui_rn = struct {
+ const param_str = "Uid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ui_rp = struct {
+ const param_str = "Uid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ui_rz = struct {
+ const param_str = "Uid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ull_rm = struct {
+ const param_str = "ULLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ull_rn = struct {
+ const param_str = "ULLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ull_rp = struct {
+ const param_str = "ULLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_d2ull_rz = struct {
+ const param_str = "ULLid";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_approx_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_approx_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rm_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rm_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rm_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rn_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rn_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rn_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rp_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rp_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rp_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rz_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_div_rz_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ex2_approx_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ex2_approx_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ex2_approx_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2h_rn = struct {
+ const param_str = "Usf";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2h_rn_ftz = struct {
+ const param_str = "Usf";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rm = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rm_ftz = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rn = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rn_ftz = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rp = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rp_ftz = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rz = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2i_rz_ftz = struct {
+ const param_str = "if";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rm = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rm_ftz = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rn = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rn_ftz = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rp = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rp_ftz = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rz = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ll_rz_ftz = struct {
+ const param_str = "LLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rm = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rm_ftz = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rn = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rn_ftz = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rp = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rp_ftz = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rz = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ui_rz_ftz = struct {
+ const param_str = "Uif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rm = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rm_ftz = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rn = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rn_ftz = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rp = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rp_ftz = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rz = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_f2ull_rz_ftz = struct {
+ const param_str = "ULLif";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fabs_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fabs_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fabs_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_floor_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_floor_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_floor_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rm_d = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rm_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rm_ftz_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rn_d = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rn_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rn_ftz_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rp_d = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rp_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rp_ftz_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rz_d = struct {
+ const param_str = "dddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rz_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fma_rz_ftz_f = struct {
+ const param_str = "ffff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fmax_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fmax_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fmax_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fmin_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fmin_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_fmin_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2d_rm = struct {
+ const param_str = "di";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2d_rn = struct {
+ const param_str = "di";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2d_rp = struct {
+ const param_str = "di";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2d_rz = struct {
+ const param_str = "di";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2f_rm = struct {
+ const param_str = "fi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2f_rn = struct {
+ const param_str = "fi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2f_rp = struct {
+ const param_str = "fi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_i2f_rz = struct {
+ const param_str = "fi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_isspacep_const = struct {
+ const param_str = "bvC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_isspacep_global = struct {
+ const param_str = "bvC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_isspacep_local = struct {
+ const param_str = "bvC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_isspacep_shared = struct {
+ const param_str = "bvC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_ldg_c = struct {
+ const param_str = "ccC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_c2 = struct {
+ const param_str = "E2cE2cC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_c4 = struct {
+ const param_str = "E4cE4cC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_d = struct {
+ const param_str = "ddC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_d2 = struct {
+ const param_str = "E2dE2dC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_f = struct {
+ const param_str = "ffC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_f2 = struct {
+ const param_str = "E2fE2fC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_f4 = struct {
+ const param_str = "E4fE4fC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_i = struct {
+ const param_str = "iiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_i2 = struct {
+ const param_str = "E2iE2iC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_i4 = struct {
+ const param_str = "E4iE4iC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_l = struct {
+ const param_str = "LiLiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ll = struct {
+ const param_str = "LLiLLiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ll2 = struct {
+ const param_str = "E2LLiE2LLiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_s = struct {
+ const param_str = "ssC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_s2 = struct {
+ const param_str = "E2sE2sC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_s4 = struct {
+ const param_str = "E4sE4sC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_uc = struct {
+ const param_str = "UcUcC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_uc2 = struct {
+ const param_str = "E2UcE2UcC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_uc4 = struct {
+ const param_str = "E4UcE4UcC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ui = struct {
+ const param_str = "UiUiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ui2 = struct {
+ const param_str = "E2UiE2UiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ui4 = struct {
+ const param_str = "E4UiE4UiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ul = struct {
+ const param_str = "ULiULiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ull = struct {
+ const param_str = "ULLiULLiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_ull2 = struct {
+ const param_str = "E2ULLiE2ULLiC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_us = struct {
+ const param_str = "UsUsC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_us2 = struct {
+ const param_str = "E2UsE2UsC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ldg_us4 = struct {
+ const param_str = "E4UsE4UsC*";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_lg2_approx_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_lg2_approx_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_lg2_approx_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2d_rm = struct {
+ const param_str = "dLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2d_rn = struct {
+ const param_str = "dLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2d_rp = struct {
+ const param_str = "dLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2d_rz = struct {
+ const param_str = "dLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2f_rm = struct {
+ const param_str = "fLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2f_rn = struct {
+ const param_str = "fLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2f_rp = struct {
+ const param_str = "fLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ll2f_rz = struct {
+ const param_str = "fLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_lohi_i2d = struct {
+ const param_str = "dii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_membar_cta = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_membar_gl = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_membar_sys = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_memcpy = struct {
+ const param_str = "vUc*Uc*zi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_memset = struct {
+ const param_str = "vUc*Uczi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul24_i = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul24_ui = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rm_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rm_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rm_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rn_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rn_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rn_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rp_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rp_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rp_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rz_d = struct {
+ const param_str = "ddd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mul_rz_ftz_f = struct {
+ const param_str = "fff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mulhi_i = struct {
+ const param_str = "iii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mulhi_ll = struct {
+ const param_str = "LLiLLiLLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mulhi_ui = struct {
+ const param_str = "UiUiUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_mulhi_ull = struct {
+ const param_str = "ULLiULLiULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_prmt = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_approx_ftz_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_approx_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rm_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rm_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rm_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rn_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rn_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rn_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rp_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rp_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rp_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rz_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rcp_rz_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_read_ptx_sreg_clock = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_read_ptx_sreg_clock64 = struct {
+ const param_str = "LLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_read_ptx_sreg_ctaid_w = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_ctaid_x = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_ctaid_y = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_ctaid_z = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_gridid = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_laneid = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_lanemask_eq = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_lanemask_ge = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_lanemask_gt = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_lanemask_le = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_lanemask_lt = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_nctaid_w = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_nctaid_x = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_nctaid_y = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_nctaid_z = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_nsmid = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_ntid_w = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_ntid_x = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_ntid_y = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_ntid_z = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_nwarpid = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_pm0 = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_read_ptx_sreg_pm1 = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_read_ptx_sreg_pm2 = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_read_ptx_sreg_pm3 = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{};
+ };
+
+ pub const __nvvm_read_ptx_sreg_smid = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_tid_w = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_tid_x = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_tid_y = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_tid_z = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_read_ptx_sreg_warpid = struct {
+ const param_str = "i";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __nvvm_round_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_round_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_round_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rsqrt_approx_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rsqrt_approx_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_rsqrt_approx_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sad_i = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sad_ui = struct {
+ const param_str = "UiUiUiUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_saturate_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_saturate_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_saturate_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_bfly_f32 = struct {
+ const param_str = "ffii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_bfly_i32 = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_down_f32 = struct {
+ const param_str = "ffii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_down_i32 = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_idx_f32 = struct {
+ const param_str = "ffii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_idx_i32 = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_up_f32 = struct {
+ const param_str = "ffii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_shfl_up_i32 = struct {
+ const param_str = "iiii";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sin_approx_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sin_approx_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_approx_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_approx_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rm_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rm_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rm_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rn_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rn_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rn_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rp_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rp_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rp_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rz_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_sqrt_rz_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_trunc_d = struct {
+ const param_str = "dd";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_trunc_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_trunc_ftz_f = struct {
+ const param_str = "ff";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2d_rm = struct {
+ const param_str = "dUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2d_rn = struct {
+ const param_str = "dUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2d_rp = struct {
+ const param_str = "dUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2d_rz = struct {
+ const param_str = "dUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2f_rm = struct {
+ const param_str = "fUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2f_rn = struct {
+ const param_str = "fUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2f_rp = struct {
+ const param_str = "fUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ui2f_rz = struct {
+ const param_str = "fUi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2d_rm = struct {
+ const param_str = "dULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2d_rn = struct {
+ const param_str = "dULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2d_rp = struct {
+ const param_str = "dULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2d_rz = struct {
+ const param_str = "dULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2f_rm = struct {
+ const param_str = "fULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2f_rn = struct {
+ const param_str = "fULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2f_rp = struct {
+ const param_str = "fULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_ull2f_rz = struct {
+ const param_str = "fULLi";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_vote_all = struct {
+ const param_str = "bb";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_vote_any = struct {
+ const param_str = "bb";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_vote_ballot = struct {
+ const param_str = "Uib";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __nvvm_vote_uni = struct {
+ const param_str = "bb";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __popcnt = struct {
+ const param_str = "UiUi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __popcnt16 = struct {
+ const param_str = "UsUs";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __popcnt64 = struct {
+ const param_str = "UWiUWi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .@"const" = true,
+ };
+ };
+
+ pub const __rdtsc = struct {
+ const param_str = "UOi";
+ const target_set = TargetSet.init(.{
+ .x86 = true,
+ });
+ };
+
+ pub const __sev = struct {
+ const param_str = "v";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __sevl = struct {
+ const param_str = "v";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __sigsetjmp = struct {
+ const param_str = "iSJi";
+ const header = .setjmp;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const __sinpi = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __sinpif = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __sync_add_and_fetch = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_add_and_fetch_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_add_and_fetch_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_add_and_fetch_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_add_and_fetch_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_add_and_fetch_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_and_and_fetch = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_and_and_fetch_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_and_and_fetch_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_and_and_fetch_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_and_and_fetch_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_and_and_fetch_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_bool_compare_and_swap = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_bool_compare_and_swap_1 = struct {
+ const param_str = "bcD*cc.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_bool_compare_and_swap_16 = struct {
+ const param_str = "bLLLiD*LLLiLLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_bool_compare_and_swap_2 = struct {
+ const param_str = "bsD*ss.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_bool_compare_and_swap_4 = struct {
+ const param_str = "biD*ii.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_bool_compare_and_swap_8 = struct {
+ const param_str = "bLLiD*LLiLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_add = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_add_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_add_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_add_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_add_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_add_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_and = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_and_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_and_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_and_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_and_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_and_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_max = struct {
+ const param_str = "iiD*i";
+ const attributes = Attributes{};
+ };
+
+ pub const __sync_fetch_and_min = struct {
+ const param_str = "iiD*i";
+ const attributes = Attributes{};
+ };
+
+ pub const __sync_fetch_and_nand = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_nand_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_nand_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_nand_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_nand_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_nand_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_or = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_or_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_or_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_or_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_or_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_or_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_sub = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_sub_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_sub_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_sub_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_sub_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_sub_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_umax = struct {
+ const param_str = "UiUiD*Ui";
+ const attributes = Attributes{};
+ };
+
+ pub const __sync_fetch_and_umin = struct {
+ const param_str = "UiUiD*Ui";
+ const attributes = Attributes{};
+ };
+
+ pub const __sync_fetch_and_xor = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_xor_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_xor_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_xor_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_xor_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_fetch_and_xor_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_release = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_release_1 = struct {
+ const param_str = "vcD*.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_release_16 = struct {
+ const param_str = "vLLLiD*.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_release_2 = struct {
+ const param_str = "vsD*.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_release_4 = struct {
+ const param_str = "viD*.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_release_8 = struct {
+ const param_str = "vLLiD*.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_test_and_set = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_test_and_set_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_test_and_set_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_test_and_set_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_test_and_set_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_lock_test_and_set_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_nand_and_fetch = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_nand_and_fetch_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_nand_and_fetch_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_nand_and_fetch_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_nand_and_fetch_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_nand_and_fetch_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_or_and_fetch = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_or_and_fetch_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_or_and_fetch_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_or_and_fetch_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_or_and_fetch_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_or_and_fetch_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_sub_and_fetch = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_sub_and_fetch_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_sub_and_fetch_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_sub_and_fetch_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_sub_and_fetch_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_sub_and_fetch_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_swap = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_swap_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_swap_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_swap_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_swap_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_swap_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_synchronize = struct {
+ const param_str = "v";
+ const attributes = Attributes{};
+ };
+
+ pub const __sync_val_compare_and_swap = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_val_compare_and_swap_1 = struct {
+ const param_str = "ccD*cc.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_val_compare_and_swap_16 = struct {
+ const param_str = "LLLiLLLiD*LLLiLLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_val_compare_and_swap_2 = struct {
+ const param_str = "ssD*ss.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_val_compare_and_swap_4 = struct {
+ const param_str = "iiD*ii.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_val_compare_and_swap_8 = struct {
+ const param_str = "LLiLLiD*LLiLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_xor_and_fetch = struct {
+ const param_str = "v.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_xor_and_fetch_1 = struct {
+ const param_str = "ccD*c.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_xor_and_fetch_16 = struct {
+ const param_str = "LLLiLLLiD*LLLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_xor_and_fetch_2 = struct {
+ const param_str = "ssD*s.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_xor_and_fetch_4 = struct {
+ const param_str = "iiD*i.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __sync_xor_and_fetch_8 = struct {
+ const param_str = "LLiLLiD*LLi.";
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __syncthreads = struct {
+ const param_str = "v";
+ const target_set = TargetSet.init(.{
+ .nvptx = true,
+ });
+ };
+
+ pub const __tanpi = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __tanpif = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const __va_start = struct {
+ const param_str = "vc**.";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .custom_typecheck = true,
+ };
+ };
+
+ pub const __warn_memset_zero_len = struct {
+ const param_str = "v";
+ const attributes = Attributes{
+ .pure = true,
+ };
+ };
+
+ pub const __wfe = struct {
+ const param_str = "v";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __wfi = struct {
+ const param_str = "v";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const __xray_customevent = struct {
+ const param_str = "vcC*z";
+ };
+
+ pub const __xray_typedevent = struct {
+ const param_str = "vzcC*z";
+ };
+
+ pub const __yield = struct {
+ const param_str = "v";
+ const language = .all_ms_languages;
+ const target_set = TargetSet.init(.{
+ .aarch64 = true,
+ .arm = true,
+ });
+ };
+
+ pub const _abnormal_termination = struct {
+ const param_str = "i";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _alloca = struct {
+ const param_str = "v*z";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittest = struct {
+ const param_str = "UcNiC*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittest64 = struct {
+ const param_str = "UcWiC*Wi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittestandcomplement = struct {
+ const param_str = "UcNi*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittestandcomplement64 = struct {
+ const param_str = "UcWi*Wi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittestandreset = struct {
+ const param_str = "UcNi*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittestandreset64 = struct {
+ const param_str = "UcWi*Wi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittestandset = struct {
+ const param_str = "UcNi*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _bittestandset64 = struct {
+ const param_str = "UcWi*Wi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _byteswap_uint64 = struct {
+ const param_str = "ULLiULLi";
+ const language = .all_ms_languages;
+ const header = .stdlib;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _byteswap_ulong = struct {
+ const param_str = "UNiUNi";
+ const language = .all_ms_languages;
+ const header = .stdlib;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _byteswap_ushort = struct {
+ const param_str = "UsUs";
+ const language = .all_ms_languages;
+ const header = .stdlib;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _exception_code = struct {
+ const param_str = "UNi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _exception_info = struct {
+ const param_str = "v*";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _exit = struct {
+ const param_str = "vi";
+ const language = .all_gnu_languages;
+ const header = .unistd;
+ const attributes = Attributes{
+ .noreturn = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _interlockedbittestandreset = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandreset64 = struct {
+ const param_str = "UcWiD*Wi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandreset_acq = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandreset_nf = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandreset_rel = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandset = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandset64 = struct {
+ const param_str = "UcWiD*Wi";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandset_acq = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandset_nf = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _interlockedbittestandset_rel = struct {
+ const param_str = "UcNiD*Ni";
+ const language = .all_ms_languages;
+ const attributes = Attributes{};
+ };
+
+ pub const _longjmp = struct {
+ const param_str = "vJi";
+ const language = .all_gnu_languages;
+ const header = .setjmp;
+ const attributes = Attributes{
+ .noreturn = true,
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const _lrotl = struct {
+ const param_str = "ULiULii";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _lrotr = struct {
+ const param_str = "ULiULii";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotl = struct {
+ const param_str = "UiUii";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotl16 = struct {
+ const param_str = "UsUsUc";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotl64 = struct {
+ const param_str = "UWiUWii";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotl8 = struct {
+ const param_str = "UcUcUc";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotr = struct {
+ const param_str = "UiUii";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotr16 = struct {
+ const param_str = "UsUsUc";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotr64 = struct {
+ const param_str = "UWiUWii";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _rotr8 = struct {
+ const param_str = "UcUcUc";
+ const language = .all_ms_languages;
+ const attributes = Attributes{
+ .const_evaluable = true,
+ };
+ };
+
+ pub const _setjmp = struct {
+ const param_str = "iJ";
+ const header = .setjmp;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const _setjmpex = struct {
+ const param_str = "iJ";
+ const language = .all_ms_languages;
+ const header = .setjmpex;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const abort = struct {
+ const param_str = "v";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .noreturn = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const abs = struct {
+ const param_str = "ii";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const acos = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const acosf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const acosh = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const acoshf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const acoshl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const acosl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const aligned_alloc = struct {
+ const param_str = "v*zz";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const alloca = struct {
+ const param_str = "v*z";
+ const language = .all_gnu_languages;
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const asin = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const asinf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const asinh = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const asinhf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const asinhl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const asinl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atan = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atan2 = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atan2f = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atan2l = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atanf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atanh = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atanhf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atanhl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const atanl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const bcmp = struct {
+ const param_str = "ivC*vC*z";
+ const language = .all_gnu_languages;
+ const header = .strings;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const bzero = struct {
+ const param_str = "vv*z";
+ const language = .all_gnu_languages;
+ const header = .strings;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cabs = struct {
+ const param_str = "dXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cabsf = struct {
+ const param_str = "fXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cabsl = struct {
+ const param_str = "LdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cacos = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cacosf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cacosh = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cacoshf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cacoshl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cacosl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const calloc = struct {
+ const param_str = "v*zz";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const carg = struct {
+ const param_str = "dXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cargf = struct {
+ const param_str = "fXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cargl = struct {
+ const param_str = "LdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const casin = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const casinf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const casinh = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const casinhf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const casinhl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const casinl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const catan = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const catanf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const catanh = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const catanhf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const catanhl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const catanl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cbrt = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cbrtf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cbrtl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const ccos = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ccosf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ccosh = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ccoshf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ccoshl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ccosl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ceil = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const ceilf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const ceill = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cexp = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cexpf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cexpl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cimag = struct {
+ const param_str = "dXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cimagf = struct {
+ const param_str = "fXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cimagl = struct {
+ const param_str = "LdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const clog = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const clogf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const clogl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const conj = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const conjf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const conjl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const copysign = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const copysignf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const copysignl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cos = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cosf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cosh = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const coshf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const coshl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cosl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cpow = struct {
+ const param_str = "XdXdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cpowf = struct {
+ const param_str = "XfXfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cpowl = struct {
+ const param_str = "XLdXLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const cproj = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cprojf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const cprojl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const creal = struct {
+ const param_str = "dXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const crealf = struct {
+ const param_str = "fXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const creall = struct {
+ const param_str = "LdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const csin = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csinf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csinh = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csinhf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csinhl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csinl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csqrt = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csqrtf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const csqrtl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ctan = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ctanf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ctanh = struct {
+ const param_str = "XdXd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ctanhf = struct {
+ const param_str = "XfXf";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ctanhl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ctanl = struct {
+ const param_str = "XLdXLd";
+ const header = .complex;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const erf = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const erfc = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const erfcf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const erfcl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const erff = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const erfl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const exit = struct {
+ const param_str = "vi";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .noreturn = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const exp = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const exp2 = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const exp2f = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const exp2l = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const expf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const expl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const expm1 = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const expm1f = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const expm1l = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fabs = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fabsf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fabsl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fdim = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fdimf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fdiml = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const finite = struct {
+ const param_str = "id";
+ const language = .gnu_lang;
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const finitef = struct {
+ const param_str = "if";
+ const language = .gnu_lang;
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const finitel = struct {
+ const param_str = "iLd";
+ const language = .gnu_lang;
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const floor = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const floorf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const floorl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fma = struct {
+ const param_str = "dddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fmaf = struct {
+ const param_str = "ffff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fmal = struct {
+ const param_str = "LdLdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fmax = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fmaxf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fmaxl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fmin = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fminf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fminl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fmod = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fmodf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fmodl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const fopen = struct {
+ const param_str = "P*cC*cC*";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fprintf = struct {
+ const param_str = "iP*cC*.";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const fread = struct {
+ const param_str = "zv*zzP*";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const free = struct {
+ const param_str = "vv*";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const frexp = struct {
+ const param_str = "ddi*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const frexpf = struct {
+ const param_str = "ffi*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const frexpl = struct {
+ const param_str = "LdLdi*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const fscanf = struct {
+ const param_str = "iP*RcC*R.";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .scanf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const fwrite = struct {
+ const param_str = "zvC*zzP*";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const getcontext = struct {
+ const param_str = "iK*";
+ const header = .setjmp;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const hypot = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const hypotf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const hypotl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ilogb = struct {
+ const param_str = "id";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ilogbf = struct {
+ const param_str = "if";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ilogbl = struct {
+ const param_str = "iLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const index = struct {
+ const param_str = "c*cC*i";
+ const language = .all_gnu_languages;
+ const header = .strings;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isalnum = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isalpha = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isblank = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const iscntrl = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isdigit = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isgraph = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const islower = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isprint = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const ispunct = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isspace = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isupper = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const isxdigit = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const labs = struct {
+ const param_str = "LiLi";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const ldexp = struct {
+ const param_str = "ddi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ldexpf = struct {
+ const param_str = "ffi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const ldexpl = struct {
+ const param_str = "LdLdi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const lgamma = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const lgammaf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const lgammal = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const llabs = struct {
+ const param_str = "LLiLLi";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const llrint = struct {
+ const param_str = "LLid";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const llrintf = struct {
+ const param_str = "LLif";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const llrintl = struct {
+ const param_str = "LLiLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const llround = struct {
+ const param_str = "LLid";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const llroundf = struct {
+ const param_str = "LLif";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const llroundl = struct {
+ const param_str = "LLiLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log10 = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log10f = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log10l = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log1p = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log1pf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log1pl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log2 = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log2f = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const log2l = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const logb = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const logbf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const logbl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const logf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const logl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const longjmp = struct {
+ const param_str = "vJi";
+ const header = .setjmp;
+ const attributes = Attributes{
+ .noreturn = true,
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const lrint = struct {
+ const param_str = "Lid";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const lrintf = struct {
+ const param_str = "Lif";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const lrintl = struct {
+ const param_str = "LiLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const lround = struct {
+ const param_str = "Lid";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const lroundf = struct {
+ const param_str = "Lif";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const lroundl = struct {
+ const param_str = "LiLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const malloc = struct {
+ const param_str = "v*z";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const memalign = struct {
+ const param_str = "v*zz";
+ const language = .all_gnu_languages;
+ const header = .malloc;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const memccpy = struct {
+ const param_str = "v*v*vC*iz";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const memchr = struct {
+ const param_str = "v*vC*iz";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const memcmp = struct {
+ const param_str = "ivC*vC*z";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const memcpy = struct {
+ const param_str = "v*v*vC*z";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const memmove = struct {
+ const param_str = "v*v*vC*z";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const mempcpy = struct {
+ const param_str = "v*v*vC*z";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const memset = struct {
+ const param_str = "v*v*iz";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const modf = struct {
+ const param_str = "ddd*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const modff = struct {
+ const param_str = "fff*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const modfl = struct {
+ const param_str = "LdLdLd*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const nan = struct {
+ const param_str = "dcC*";
+ const header = .math;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const nanf = struct {
+ const param_str = "fcC*";
+ const header = .math;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const nanl = struct {
+ const param_str = "LdcC*";
+ const header = .math;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const nearbyint = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const nearbyintf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const nearbyintl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const nextafter = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const nextafterf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const nextafterl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const nexttoward = struct {
+ const param_str = "ddLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const nexttowardf = struct {
+ const param_str = "ffLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const nexttowardl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const pow = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const powf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const powl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const printf = struct {
+ const param_str = "icC*.";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 0,
+ };
+ };
+
+ pub const realloc = struct {
+ const param_str = "v*v*z";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const remainder = struct {
+ const param_str = "ddd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const remainderf = struct {
+ const param_str = "fff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const remainderl = struct {
+ const param_str = "LdLdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const remquo = struct {
+ const param_str = "dddi*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const remquof = struct {
+ const param_str = "fffi*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const remquol = struct {
+ const param_str = "LdLdLdi*";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const rindex = struct {
+ const param_str = "c*cC*i";
+ const language = .all_gnu_languages;
+ const header = .strings;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const rint = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_fp_exceptions = true,
+ };
+ };
+
+ pub const rintf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_fp_exceptions = true,
+ };
+ };
+
+ pub const rintl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_fp_exceptions = true,
+ };
+ };
+
+ pub const round = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const roundf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const roundl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const savectx = struct {
+ const param_str = "iJ";
+ const header = .setjmp;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const scalbln = struct {
+ const param_str = "ddLi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const scalblnf = struct {
+ const param_str = "ffLi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const scalblnl = struct {
+ const param_str = "LdLdLi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const scalbn = struct {
+ const param_str = "ddi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const scalbnf = struct {
+ const param_str = "ffi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const scalbnl = struct {
+ const param_str = "LdLdi";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const scanf = struct {
+ const param_str = "icC*R.";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .scanf,
+ .format_string_position = 0,
+ };
+ };
+
+ pub const setjmp = struct {
+ const param_str = "iJ";
+ const header = .setjmp;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const siglongjmp = struct {
+ const param_str = "vSJi";
+ const language = .all_gnu_languages;
+ const header = .setjmp;
+ const attributes = Attributes{
+ .noreturn = true,
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const sigsetjmp = struct {
+ const param_str = "iSJi";
+ const header = .setjmp;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const sin = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sinf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sinh = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sinhf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sinhl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sinl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const snprintf = struct {
+ const param_str = "ic*zcC*.";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 2,
+ };
+ };
+
+ pub const sprintf = struct {
+ const param_str = "ic*cC*.";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .printf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const sqrt = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sqrtf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sqrtl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const sscanf = struct {
+ const param_str = "icC*RcC*R.";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .scanf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const stpcpy = struct {
+ const param_str = "c*c*cC*";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const stpncpy = struct {
+ const param_str = "c*c*cC*z";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strcasecmp = struct {
+ const param_str = "icC*cC*";
+ const language = .all_gnu_languages;
+ const header = .strings;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strcat = struct {
+ const param_str = "c*c*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strchr = struct {
+ const param_str = "c*cC*i";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const strcmp = struct {
+ const param_str = "icC*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const strcpy = struct {
+ const param_str = "c*c*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strcspn = struct {
+ const param_str = "zcC*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strdup = struct {
+ const param_str = "c*cC*";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strerror = struct {
+ const param_str = "c*i";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strlcat = struct {
+ const param_str = "zc*cC*z";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strlcpy = struct {
+ const param_str = "zc*cC*z";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strlen = struct {
+ const param_str = "zcC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const strncasecmp = struct {
+ const param_str = "icC*cC*z";
+ const language = .all_gnu_languages;
+ const header = .strings;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strncat = struct {
+ const param_str = "c*c*cC*z";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strncmp = struct {
+ const param_str = "icC*cC*z";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const strncpy = struct {
+ const param_str = "c*c*cC*z";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strndup = struct {
+ const param_str = "c*cC*z";
+ const language = .all_gnu_languages;
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strpbrk = struct {
+ const param_str = "c*cC*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strrchr = struct {
+ const param_str = "c*cC*i";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strspn = struct {
+ const param_str = "zcC*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strstr = struct {
+ const param_str = "c*cC*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtod = struct {
+ const param_str = "dcC*c**";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtof = struct {
+ const param_str = "fcC*c**";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtok = struct {
+ const param_str = "c*c*cC*";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtol = struct {
+ const param_str = "LicC*c**i";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtold = struct {
+ const param_str = "LdcC*c**";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtoll = struct {
+ const param_str = "LLicC*c**i";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtoul = struct {
+ const param_str = "ULicC*c**i";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strtoull = struct {
+ const param_str = "ULLicC*c**i";
+ const header = .stdlib;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const strxfrm = struct {
+ const param_str = "zc*cC*z";
+ const header = .string;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const tan = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tanf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tanh = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tanhf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tanhl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tanl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tgamma = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tgammaf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tgammal = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_without_errno_and_fp_exceptions = true,
+ };
+ };
+
+ pub const tolower = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const toupper = struct {
+ const param_str = "ii";
+ const header = .ctype;
+ const attributes = Attributes{
+ .pure = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const trunc = struct {
+ const param_str = "dd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const truncf = struct {
+ const param_str = "ff";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const truncl = struct {
+ const param_str = "LdLd";
+ const header = .math;
+ const attributes = Attributes{
+ .@"const" = true,
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const va_copy = struct {
+ const param_str = "vAA";
+ const header = .stdarg;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const va_end = struct {
+ const param_str = "vA";
+ const header = .stdarg;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const va_start = struct {
+ const param_str = "vA.";
+ const header = .stdarg;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ };
+ };
+
+ pub const vfork = struct {
+ const param_str = "p";
+ const header = .unistd;
+ const attributes = Attributes{
+ .allow_type_mismatch = true,
+ .lib_function_without_prefix = true,
+ .returns_twice = true,
+ };
+ };
+
+ pub const vfprintf = struct {
+ const param_str = "iP*cC*a";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const vfscanf = struct {
+ const param_str = "iP*RcC*Ra";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .vscanf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const vprintf = struct {
+ const param_str = "icC*a";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 0,
+ };
+ };
+
+ pub const vscanf = struct {
+ const param_str = "icC*Ra";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .vscanf,
+ .format_string_position = 0,
+ };
+ };
+
+ pub const vsnprintf = struct {
+ const param_str = "ic*zcC*a";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 2,
+ };
+ };
+
+ pub const vsprintf = struct {
+ const param_str = "ic*cC*a";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .vprintf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const vsscanf = struct {
+ const param_str = "icC*RcC*Ra";
+ const header = .stdio;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .format_kind = .vscanf,
+ .format_string_position = 1,
+ };
+ };
+
+ pub const wcschr = struct {
+ const param_str = "w*wC*w";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const wcscmp = struct {
+ const param_str = "iwC*wC*";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const wcslen = struct {
+ const param_str = "zwC*";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const wcsncmp = struct {
+ const param_str = "iwC*wC*z";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const wmemchr = struct {
+ const param_str = "w*wC*wz";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const wmemcmp = struct {
+ const param_str = "iwC*wC*z";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const wmemcpy = struct {
+ const param_str = "w*w*wC*z";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+
+ pub const wmemmove = struct {
+ const param_str = "w*w*wC*z";
+ const header = .wchar;
+ const attributes = Attributes{
+ .lib_function_without_prefix = true,
+ .const_evaluable = true,
+ };
+ };
+};
+pub const MaxParamCount = 12;
deps/aro/builtins/Properties.zig
@@ -0,0 +1,138 @@
+const std = @import("std");
+
+const Properties = @This();
+
+language: Language,
+attributes: Attributes,
+header: Header,
+target_set: TargetSet,
+
+/// Header which must be included for a builtin to be available
+pub const Header = enum {
+ none,
+ /// stdio.h
+ stdio,
+ /// stdlib.h
+ stdlib,
+ /// setjmpex.h
+ setjmpex,
+ /// stdarg.h
+ stdarg,
+ /// string.h
+ string,
+ /// ctype.h
+ ctype,
+ /// wchar.h
+ wchar,
+ /// setjmp.h
+ setjmp,
+ /// malloc.h
+ malloc,
+ /// strings.h
+ strings,
+ /// unistd.h
+ unistd,
+ /// pthread.h
+ pthread,
+ /// math.h
+ math,
+ /// complex.h
+ complex,
+ /// Blocks.h
+ blocks,
+};
+
+/// Languages in which a builtin is available
+pub const Language = enum {
+ all_languages,
+ all_ms_languages,
+ all_gnu_languages,
+ gnu_lang,
+};
+
+pub const Attributes = packed struct {
+ /// Function does not return
+ noreturn: bool = false,
+
+ /// Function has no side effects
+ pure: bool = false,
+
+ /// Function has no side effects and does not read memory
+ @"const": bool = false,
+
+ /// Signature is meaningless; use custom typecheck
+ custom_typecheck: bool = false,
+
+ /// A declaration of this builtin should be recognized even if the type doesn't match the specified signature.
+ allow_type_mismatch: bool = false,
+
+ /// this is a libc/libm function with a '__builtin_' prefix added.
+ lib_function_with_builtin_prefix: bool = false,
+
+ /// this is a libc/libm function without a '__builtin_' prefix. This builtin is disableable by '-fno-builtin-foo'
+ lib_function_without_prefix: bool = false,
+
+ /// Function returns twice (e.g. setjmp)
+ returns_twice: bool = false,
+
+ /// Nature of the format string passed to this function
+ format_kind: enum(u3) {
+ /// Does not take a format string
+ none,
+ /// this is a printf-like function whose Nth argument is the format string
+ printf,
+ /// function is like vprintf in that it accepts its arguments as a va_list rather than through an ellipsis
+ vprintf,
+ /// this is a scanf-like function whose Nth argument is the format string
+ scanf,
+ /// the function is like vscanf in that it accepts its arguments as a va_list rather than through an ellipsis
+ vscanf,
+ } = .none,
+
+ /// Position of format string argument. Only meaningful if format_kind is not .none
+ format_string_position: u5 = 0,
+
+ /// if false, arguments are not evaluated
+ eval_args: bool = true,
+
+ /// no side effects and does not read memory, but only when -fno-math-errno and FP exceptions are ignored
+ const_without_errno_and_fp_exceptions: bool = false,
+
+ /// no side effects and does not read memory, but only when FP exceptions are ignored
+ const_without_fp_exceptions: bool = false,
+
+ /// this function can be constant evaluated by the frontend
+ const_evaluable: bool = false,
+};
+
+pub const Target = enum {
+ /// Supported on all targets
+ basic,
+ aarch64,
+ aarch64_neon_sve_bridge,
+ aarch64_neon_sve_bridge_cg,
+ amdgpu,
+ arm,
+ bpf,
+ hexagon,
+ hexagon_dep,
+ hexagon_map_custom_dep,
+ loong_arch,
+ mips,
+ neon,
+ nvptx,
+ ppc,
+ riscv,
+ riscv_vector,
+ sve,
+ systemz,
+ ve,
+ vevl_gen,
+ webassembly,
+ x86,
+ x86_64,
+ xcore,
+};
+
+/// Targets for which a builtin is enabled
+pub const TargetSet = std.enums.EnumSet(Target);
deps/aro/builtins/TypeDescription.zig
@@ -0,0 +1,277 @@
+const std = @import("std");
+
+const TypeDescription = @This();
+
+prefix: []const Prefix,
+spec: Spec,
+suffix: []const Suffix,
+
+pub const Component = union(enum) {
+ prefix: Prefix,
+ spec: Spec,
+ suffix: Suffix,
+};
+
+pub const ComponentIterator = struct {
+ str: []const u8,
+ idx: usize,
+
+ pub fn init(str: []const u8) ComponentIterator {
+ return .{
+ .str = str,
+ .idx = 0,
+ };
+ }
+
+ pub fn peek(self: *ComponentIterator) ?Component {
+ const idx = self.idx;
+ defer self.idx = idx;
+ return self.next();
+ }
+
+ pub fn next(self: *ComponentIterator) ?Component {
+ if (self.idx == self.str.len) return null;
+ const c = self.str[self.idx];
+ self.idx += 1;
+ switch (c) {
+ 'L' => {
+ if (self.str[self.idx] != 'L') return .{ .prefix = .L };
+ self.idx += 1;
+ if (self.str[self.idx] != 'L') return .{ .prefix = .LL };
+ self.idx += 1;
+ return .{ .prefix = .LLL };
+ },
+ 'Z' => return .{ .prefix = .Z },
+ 'W' => return .{ .prefix = .W },
+ 'N' => return .{ .prefix = .N },
+ 'O' => return .{ .prefix = .O },
+ 'S' => {
+ if (self.str[self.idx] == 'J') {
+ self.idx += 1;
+ return .{ .spec = .SJ };
+ }
+ return .{ .prefix = .S };
+ },
+ 'U' => return .{ .prefix = .U },
+ 'I' => return .{ .prefix = .I },
+
+ 'v' => return .{ .spec = .v },
+ 'b' => return .{ .spec = .b },
+ 'c' => return .{ .spec = .c },
+ 's' => return .{ .spec = .s },
+ 'i' => return .{ .spec = .i },
+ 'h' => return .{ .spec = .h },
+ 'x' => return .{ .spec = .x },
+ 'y' => return .{ .spec = .y },
+ 'f' => return .{ .spec = .f },
+ 'd' => return .{ .spec = .d },
+ 'z' => return .{ .spec = .z },
+ 'w' => return .{ .spec = .w },
+ 'F' => return .{ .spec = .F },
+ 'a' => return .{ .spec = .a },
+ 'A' => return .{ .spec = .A },
+ 'V', 'q', 'E' => {
+ const start = self.idx;
+ while (std.ascii.isDigit(self.str[self.idx])) : (self.idx += 1) {}
+ const count = std.fmt.parseUnsigned(u32, self.str[start..self.idx], 10) catch unreachable;
+ return switch (c) {
+ 'V' => .{ .spec = .{ .V = count } },
+ 'q' => .{ .spec = .{ .q = count } },
+ 'E' => .{ .spec = .{ .E = count } },
+ else => unreachable,
+ };
+ },
+ 'X' => {
+ defer self.idx += 1;
+ switch (self.str[self.idx]) {
+ 'f' => return .{ .spec = .{ .X = .float } },
+ 'd' => return .{ .spec = .{ .X = .double } },
+ 'L' => {
+ self.idx += 1;
+ return .{ .spec = .{ .X = .longdouble } };
+ },
+ else => unreachable,
+ }
+ },
+ 'Y' => return .{ .spec = .Y },
+ 'P' => return .{ .spec = .P },
+ 'J' => return .{ .spec = .J },
+ 'K' => return .{ .spec = .K },
+ 'p' => return .{ .spec = .p },
+ '.' => {
+ // can only appear at end of param string; indicates varargs function
+ std.debug.assert(self.idx == self.str.len);
+ return null;
+ },
+ '!' => {
+ std.debug.assert(self.str.len == 1);
+ return .{ .spec = .@"!" };
+ },
+
+ '*' => {
+ if (self.idx < self.str.len and std.ascii.isDigit(self.str[self.idx])) {
+ defer self.idx += 1;
+ const addr_space = self.str[self.idx] - '0';
+ return .{ .suffix = .{ .@"*" = addr_space } };
+ } else {
+ return .{ .suffix = .{ .@"*" = null } };
+ }
+ },
+ 'C' => return .{ .suffix = .C },
+ 'D' => return .{ .suffix = .D },
+ 'R' => return .{ .suffix = .R },
+ else => unreachable,
+ }
+ return null;
+ }
+};
+
+pub const TypeIterator = struct {
+ param_str: []const u8,
+ prefix: [4]Prefix,
+ spec: Spec,
+ suffix: [4]Suffix,
+ idx: usize,
+
+ pub fn init(param_str: []const u8) TypeIterator {
+ return .{
+ .param_str = param_str,
+ .prefix = undefined,
+ .spec = undefined,
+ .suffix = undefined,
+ .idx = 0,
+ };
+ }
+
+ /// Returned `TypeDescription` contains fields which are slices into the underlying `TypeIterator`
+ /// The returned value is invalidated when `.next()` is called again or the TypeIterator goes out
+ // of scope.
+ pub fn next(self: *TypeIterator) ?TypeDescription {
+ var it = ComponentIterator.init(self.param_str[self.idx..]);
+ defer self.idx += it.idx;
+
+ var prefix_count: usize = 0;
+ var maybe_spec: ?Spec = null;
+ var suffix_count: usize = 0;
+ while (it.peek()) |component| {
+ switch (component) {
+ .prefix => |prefix| {
+ if (maybe_spec != null) break;
+ self.prefix[prefix_count] = prefix;
+ prefix_count += 1;
+ },
+ .spec => |spec| {
+ if (maybe_spec != null) break;
+ maybe_spec = spec;
+ },
+ .suffix => |suffix| {
+ std.debug.assert(maybe_spec != null);
+ self.suffix[suffix_count] = suffix;
+ suffix_count += 1;
+ },
+ }
+ _ = it.next();
+ }
+ if (maybe_spec) |spec| {
+ return TypeDescription{
+ .prefix = self.prefix[0..prefix_count],
+ .spec = spec,
+ .suffix = self.suffix[0..suffix_count],
+ };
+ }
+ return null;
+ }
+};
+
+const Prefix = enum {
+ /// long (e.g. Li for 'long int', Ld for 'long double')
+ L,
+ /// long long (e.g. LLi for 'long long int', LLd for __float128)
+ LL,
+ /// __int128_t (e.g. LLLi)
+ LLL,
+ /// int32_t (require a native 32-bit integer type on the target)
+ Z,
+ /// int64_t (require a native 64-bit integer type on the target)
+ W,
+ /// 'int' size if target is LP64, 'L' otherwise.
+ N,
+ /// long for OpenCL targets, long long otherwise.
+ O,
+ /// signed
+ S,
+ /// unsigned
+ U,
+ /// Required to constant fold to an integer constant expression.
+ I,
+};
+
+const Spec = union(enum) {
+ /// void
+ v,
+ /// boolean
+ b,
+ /// char
+ c,
+ /// short
+ s,
+ /// int
+ i,
+ /// half (__fp16, OpenCL)
+ h,
+ /// half (_Float16)
+ x,
+ /// half (__bf16)
+ y,
+ /// float
+ f,
+ /// double
+ d,
+ /// size_t
+ z,
+ /// wchar_t
+ w,
+ /// constant CFString
+ F,
+ /// __builtin_va_list
+ a,
+ /// "reference" to __builtin_va_list
+ A,
+ /// Vector, followed by the number of elements and the base type.
+ V: u32,
+ /// Scalable vector, followed by the number of elements and the base type.
+ q: u32,
+ /// ext_vector, followed by the number of elements and the base type.
+ E: u32,
+ /// _Complex, followed by the base type.
+ X: enum {
+ float,
+ double,
+ longdouble,
+ },
+ /// ptrdiff_t
+ Y,
+ /// FILE
+ P,
+ /// jmp_buf
+ J,
+ /// sigjmp_buf
+ SJ,
+ /// ucontext_t
+ K,
+ /// pid_t
+ p,
+ /// Used to indicate a builtin with target-dependent param types. Must appear by itself
+ @"!",
+};
+
+const Suffix = union(enum) {
+ /// pointer (optionally followed by an address space number,if no address space is specified than any address space will be accepted)
+ @"*": ?u8,
+ /// const
+ C,
+ /// volatile
+ D,
+ /// restrict
+ R,
+};
deps/aro/codegen/x86_64.zig
@@ -0,0 +1,221 @@
+const std = @import("std");
+const Codegen = @import("../Codegen_legacy.zig");
+const Tree = @import("../Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const x86_64 = @import("zig").codegen.x86_64;
+const Register = x86_64.Register;
+const RegisterManager = @import("zig").RegisterManager;
+
+const Fn = @This();
+
+const Value = union(enum) {
+ symbol: []const u8,
+ immediate: i64,
+ register: Register,
+ none,
+};
+
+register_manager: RegisterManager(Fn, Register, &x86_64.callee_preserved_regs) = .{},
+data: *std.ArrayList(u8),
+c: *Codegen,
+
+pub fn deinit(func: *Fn) void {
+ func.* = undefined;
+}
+
+pub fn genFn(c: *Codegen, decl: NodeIndex, data: *std.ArrayList(u8)) Codegen.Error!void {
+ var func = Fn{ .data = data, .c = c };
+ defer func.deinit();
+
+ // function prologue
+ try func.data.appendSlice(&.{
+ 0x55, // push rbp
+ 0x48, 0x89, 0xe5, // mov rbp,rsp
+ });
+ _ = try func.genNode(c.node_data[@intFromEnum(decl)].decl.node);
+ // all functions are guaranteed to end in a return statement so no extra work required here
+}
+
+pub fn spillInst(f: *Fn, reg: Register, inst: u32) !void {
+ _ = inst;
+ _ = reg;
+ _ = f;
+}
+
+fn setReg(func: *Fn, val: Value, reg: Register) !void {
+ switch (val) {
+ .none => unreachable,
+ .symbol => |sym| {
+ // lea address with 0 and add relocation
+ const encoder = try x86_64.Encoder.init(func.data, 8);
+ encoder.rex(.{ .w = true });
+ encoder.opcode_1byte(0x8D);
+ encoder.modRm_RIPDisp32(reg.low_id());
+
+ const offset = func.data.items.len;
+ encoder.imm32(0);
+
+ try func.c.obj.addRelocation(sym, .func, offset, -4);
+ },
+ .immediate => |x| if (x == 0) {
+ // 32-bit moves zero-extend to 64-bit, so xoring the 32-bit
+ // register is the fastest way to zero a register.
+ // The encoding for `xor r32, r32` is `0x31 /r`.
+ const encoder = try x86_64.Encoder.init(func.data, 3);
+
+ // If we're accessing e.g. r8d, we need to use a REX prefix before the actual operation. Since
+ // this is a 32-bit operation, the W flag is set to zero. X is also zero, as we're not using a SIB.
+ // Both R and B are set, as we're extending, in effect, the register bits *and* the operand.
+ encoder.rex(.{ .r = reg.isExtended(), .b = reg.isExtended() });
+ encoder.opcode_1byte(0x31);
+ // Section 3.1.1.1 of the Intel x64 Manual states that "/r indicates that the
+ // ModR/M byte of the instruction contains a register operand and an r/m operand."
+ encoder.modRm_direct(reg.low_id(), reg.low_id());
+ } else if (x <= std.math.maxInt(i32)) {
+ // Next best case: if we set the lower four bytes, the upper four will be zeroed.
+ //
+ // The encoding for `mov IMM32 -> REG` is (0xB8 + R) IMM.
+
+ const encoder = try x86_64.Encoder.init(func.data, 6);
+ // Just as with XORing, we need a REX prefix. This time though, we only
+ // need the B bit set, as we're extending the opcode's register field,
+ // and there is no Mod R/M byte.
+ encoder.rex(.{ .b = reg.isExtended() });
+ encoder.opcode_withReg(0xB8, reg.low_id());
+
+ // no ModR/M byte
+
+ // IMM
+ encoder.imm32(@intCast(x));
+ } else {
+ // Worst case: we need to load the 64-bit register with the IMM. GNU's assemblers calls
+ // this `movabs`, though this is officially just a different variant of the plain `mov`
+ // instruction.
+ //
+ // This encoding is, in fact, the *same* as the one used for 32-bit loads. The only
+ // difference is that we set REX.W before the instruction, which extends the load to
+ // 64-bit and uses the full bit-width of the register.
+ {
+ const encoder = try x86_64.Encoder.init(func.data, 10);
+ encoder.rex(.{ .w = true, .b = reg.isExtended() });
+ encoder.opcode_withReg(0xB8, reg.low_id());
+ encoder.imm64(@bitCast(x));
+ }
+ },
+ .register => |src_reg| {
+ // If the registers are the same, nothing to do.
+ if (src_reg.id() == reg.id())
+ return;
+
+ // This is a variant of 8B /r.
+ const encoder = try x86_64.Encoder.init(func.data, 3);
+ encoder.rex(.{
+ .w = true,
+ .r = reg.isExtended(),
+ .b = src_reg.isExtended(),
+ });
+ encoder.opcode_1byte(0x8B);
+ encoder.modRm_direct(reg.low_id(), src_reg.low_id());
+ },
+ }
+}
+
+fn genNode(func: *Fn, node: NodeIndex) Codegen.Error!Value {
+ if (func.c.tree.value_map.get(node)) |some| {
+ if (some.tag == .int)
+ return Value{ .immediate = @bitCast(some.data.int) };
+ }
+
+ const data = func.c.node_data[@intFromEnum(node)];
+ switch (func.c.node_tag[@intFromEnum(node)]) {
+ .static_assert => return Value{ .none = {} },
+ .compound_stmt_two => {
+ if (data.bin.lhs != .none) _ = try func.genNode(data.bin.lhs);
+ if (data.bin.rhs != .none) _ = try func.genNode(data.bin.rhs);
+ return Value{ .none = {} };
+ },
+ .compound_stmt => {
+ for (func.c.tree.data[data.range.start..data.range.end]) |stmt| {
+ _ = try func.genNode(stmt);
+ }
+ return Value{ .none = {} };
+ },
+ .call_expr_one => if (data.bin.rhs != .none)
+ return func.genCall(data.bin.lhs, &.{data.bin.rhs})
+ else
+ return func.genCall(data.bin.lhs, &.{}),
+ .call_expr => return func.genCall(func.c.tree.data[data.range.start], func.c.tree.data[data.range.start + 1 .. data.range.end]),
+ .explicit_cast, .implicit_cast => {
+ switch (data.cast.kind) {
+ .function_to_pointer,
+ .array_to_pointer,
+ => return func.genNode(data.cast.operand), // no-op
+ else => return func.c.comp.diag.fatalNoSrc("TODO x86_64 genNode for cast {s}\n", .{@tagName(data.cast.kind)}),
+ }
+ },
+ .decl_ref_expr => {
+ // TODO locals and arguments
+ return Value{ .symbol = func.c.tree.tokSlice(data.decl_ref) };
+ },
+ .return_stmt => {
+ const value = try func.genNode(data.un);
+ try func.setReg(value, x86_64.c_abi_int_return_regs[0]);
+ try func.data.appendSlice(&.{
+ 0x5d, // pop rbp
+ 0xc3, // ret
+ });
+ return Value{ .none = {} };
+ },
+ .implicit_return => {
+ try func.setReg(.{ .immediate = 0 }, x86_64.c_abi_int_return_regs[0]);
+ try func.data.appendSlice(&.{
+ 0x5d, // pop rbp
+ 0xc3, // ret
+ });
+ return Value{ .none = {} };
+ },
+ .int_literal => return Value{ .immediate = @bitCast(data.int) },
+ .string_literal_expr => {
+ const range = func.c.tree.value_map.get(node).?.data.bytes;
+ const str_bytes = range.slice(func.c.tree.strings);
+ const section = try func.c.obj.getSection(.strings);
+ const start = section.items.len;
+ try section.appendSlice(str_bytes);
+ const symbol_name = try func.c.obj.declareSymbol(.strings, null, .Internal, .variable, start, str_bytes.len);
+ return Value{ .symbol = symbol_name };
+ },
+ else => return func.c.comp.diag.fatalNoSrc("TODO x86_64 genNode {}\n", .{func.c.node_tag[@intFromEnum(node)]}),
+ }
+}
+
+fn genCall(func: *Fn, lhs: NodeIndex, args: []const NodeIndex) Codegen.Error!Value {
+ if (args.len > x86_64.c_abi_int_param_regs.len)
+ return func.c.comp.diag.fatalNoSrc("TODO more than args {d}\n", .{x86_64.c_abi_int_param_regs.len});
+
+ const func_value = try func.genNode(lhs);
+ for (args, 0..) |arg, i| {
+ const value = try func.genNode(arg);
+ try func.setReg(value, x86_64.c_abi_int_param_regs[i]);
+ }
+
+ switch (func_value) {
+ .none => unreachable,
+ .symbol => |sym| {
+ const encoder = try x86_64.Encoder.init(func.data, 5);
+ encoder.opcode_1byte(0xe8);
+
+ const offset = func.data.items.len;
+ encoder.imm32(0);
+
+ try func.c.obj.addRelocation(sym, .func, offset, -4);
+ },
+ .immediate => return func.c.comp.diag.fatalNoSrc("TODO call immediate\n", .{}),
+ .register => return func.c.comp.diag.fatalNoSrc("TODO call reg\n", .{}),
+ }
+ return Value{ .register = x86_64.c_abi_int_return_regs[0] };
+}
+
+pub fn genVar(c: *Codegen, decl: NodeIndex) Codegen.Error!void {
+ _ = c;
+ _ = decl;
+}
deps/aro/Driver/Distro.zig
@@ -0,0 +1,329 @@
+//! Tools for figuring out what Linux distro we're running on
+
+const std = @import("std");
+const mem = std.mem;
+const util = @import("../util.zig");
+const Filesystem = @import("Filesystem.zig").Filesystem;
+
+const MAX_BYTES = 1024; // TODO: Can we assume 1024 bytes enough for the info we need?
+
+/// Value for linker `--hash-style=` argument
+pub const HashStyle = enum {
+ both,
+ gnu,
+};
+
+pub const Tag = enum {
+ alpine,
+ arch,
+ debian_lenny,
+ debian_squeeze,
+ debian_wheezy,
+ debian_jessie,
+ debian_stretch,
+ debian_buster,
+ debian_bullseye,
+ debian_bookworm,
+ debian_trixie,
+ exherbo,
+ rhel5,
+ rhel6,
+ rhel7,
+ fedora,
+ gentoo,
+ open_suse,
+ ubuntu_hardy,
+ ubuntu_intrepid,
+ ubuntu_jaunty,
+ ubuntu_karmic,
+ ubuntu_lucid,
+ ubuntu_maverick,
+ ubuntu_natty,
+ ubuntu_oneiric,
+ ubuntu_precise,
+ ubuntu_quantal,
+ ubuntu_raring,
+ ubuntu_saucy,
+ ubuntu_trusty,
+ ubuntu_utopic,
+ ubuntu_vivid,
+ ubuntu_wily,
+ ubuntu_xenial,
+ ubuntu_yakkety,
+ ubuntu_zesty,
+ ubuntu_artful,
+ ubuntu_bionic,
+ ubuntu_cosmic,
+ ubuntu_disco,
+ ubuntu_eoan,
+ ubuntu_focal,
+ ubuntu_groovy,
+ ubuntu_hirsute,
+ ubuntu_impish,
+ ubuntu_jammy,
+ ubuntu_kinetic,
+ ubuntu_lunar,
+ unknown,
+
+ pub fn getHashStyle(self: Tag) HashStyle {
+ if (self.isOpenSUSE()) return .both;
+ return switch (self) {
+ .ubuntu_lucid,
+ .ubuntu_jaunty,
+ .ubuntu_karmic,
+ => .both,
+ else => .gnu,
+ };
+ }
+
+ pub fn isRedhat(self: Tag) bool {
+ return switch (self) {
+ .fedora,
+ .rhel5,
+ .rhel6,
+ .rhel7,
+ => true,
+ else => false,
+ };
+ }
+
+ pub fn isOpenSUSE(self: Tag) bool {
+ return self == .open_suse;
+ }
+
+ pub fn isDebian(self: Tag) bool {
+ return switch (self) {
+ .debian_lenny,
+ .debian_squeeze,
+ .debian_wheezy,
+ .debian_jessie,
+ .debian_stretch,
+ .debian_buster,
+ .debian_bullseye,
+ .debian_bookworm,
+ .debian_trixie,
+ => true,
+ else => false,
+ };
+ }
+ pub fn isUbuntu(self: Tag) bool {
+ return switch (self) {
+ .ubuntu_hardy,
+ .ubuntu_intrepid,
+ .ubuntu_jaunty,
+ .ubuntu_karmic,
+ .ubuntu_lucid,
+ .ubuntu_maverick,
+ .ubuntu_natty,
+ .ubuntu_oneiric,
+ .ubuntu_precise,
+ .ubuntu_quantal,
+ .ubuntu_raring,
+ .ubuntu_saucy,
+ .ubuntu_trusty,
+ .ubuntu_utopic,
+ .ubuntu_vivid,
+ .ubuntu_wily,
+ .ubuntu_xenial,
+ .ubuntu_yakkety,
+ .ubuntu_zesty,
+ .ubuntu_artful,
+ .ubuntu_bionic,
+ .ubuntu_cosmic,
+ .ubuntu_disco,
+ .ubuntu_eoan,
+ .ubuntu_focal,
+ .ubuntu_groovy,
+ .ubuntu_hirsute,
+ .ubuntu_impish,
+ .ubuntu_jammy,
+ .ubuntu_kinetic,
+ .ubuntu_lunar,
+ => true,
+
+ else => false,
+ };
+ }
+ pub fn isAlpine(self: Tag) bool {
+ return self == .alpine;
+ }
+ pub fn isGentoo(self: Tag) bool {
+ return self == .gentoo;
+ }
+};
+
+fn scanForOsRelease(buf: []const u8) ?Tag {
+ var it = mem.splitScalar(u8, buf, '\n');
+ while (it.next()) |line| {
+ if (mem.startsWith(u8, line, "ID=")) {
+ const rest = line["ID=".len..];
+ if (mem.eql(u8, rest, "alpine")) return .alpine;
+ if (mem.eql(u8, rest, "fedora")) return .fedora;
+ if (mem.eql(u8, rest, "gentoo")) return .gentoo;
+ if (mem.eql(u8, rest, "arch")) return .arch;
+ if (mem.eql(u8, rest, "sles")) return .open_suse;
+ if (mem.eql(u8, rest, "opensuse")) return .open_suse;
+ if (mem.eql(u8, rest, "exherbo")) return .exherbo;
+ }
+ }
+ return null;
+}
+
+fn detectOsRelease(fs: Filesystem) ?Tag {
+ var buf: [MAX_BYTES]u8 = undefined;
+ const data = fs.readFile("/etc/os-release", &buf) orelse fs.readFile("/usr/lib/os-release", &buf) orelse return null;
+ return scanForOsRelease(data);
+}
+
+fn scanForLSBRelease(buf: []const u8) ?Tag {
+ var it = mem.splitScalar(u8, buf, '\n');
+ while (it.next()) |line| {
+ if (mem.startsWith(u8, line, "DISTRIB_CODENAME=")) {
+ const rest = line["DISTRIB_CODENAME=".len..];
+ if (mem.eql(u8, rest, "hardy")) return .ubuntu_hardy;
+ if (mem.eql(u8, rest, "intrepid")) return .ubuntu_intrepid;
+ if (mem.eql(u8, rest, "jaunty")) return .ubuntu_jaunty;
+ if (mem.eql(u8, rest, "karmic")) return .ubuntu_karmic;
+ if (mem.eql(u8, rest, "lucid")) return .ubuntu_lucid;
+ if (mem.eql(u8, rest, "maverick")) return .ubuntu_maverick;
+ if (mem.eql(u8, rest, "natty")) return .ubuntu_natty;
+ if (mem.eql(u8, rest, "oneiric")) return .ubuntu_oneiric;
+ if (mem.eql(u8, rest, "precise")) return .ubuntu_precise;
+ if (mem.eql(u8, rest, "quantal")) return .ubuntu_quantal;
+ if (mem.eql(u8, rest, "raring")) return .ubuntu_raring;
+ if (mem.eql(u8, rest, "saucy")) return .ubuntu_saucy;
+ if (mem.eql(u8, rest, "trusty")) return .ubuntu_trusty;
+ if (mem.eql(u8, rest, "utopic")) return .ubuntu_utopic;
+ if (mem.eql(u8, rest, "vivid")) return .ubuntu_vivid;
+ if (mem.eql(u8, rest, "wily")) return .ubuntu_wily;
+ if (mem.eql(u8, rest, "xenial")) return .ubuntu_xenial;
+ if (mem.eql(u8, rest, "yakkety")) return .ubuntu_yakkety;
+ if (mem.eql(u8, rest, "zesty")) return .ubuntu_zesty;
+ if (mem.eql(u8, rest, "artful")) return .ubuntu_artful;
+ if (mem.eql(u8, rest, "bionic")) return .ubuntu_bionic;
+ if (mem.eql(u8, rest, "cosmic")) return .ubuntu_cosmic;
+ if (mem.eql(u8, rest, "disco")) return .ubuntu_disco;
+ if (mem.eql(u8, rest, "eoan")) return .ubuntu_eoan;
+ if (mem.eql(u8, rest, "focal")) return .ubuntu_focal;
+ if (mem.eql(u8, rest, "groovy")) return .ubuntu_groovy;
+ if (mem.eql(u8, rest, "hirsute")) return .ubuntu_hirsute;
+ if (mem.eql(u8, rest, "impish")) return .ubuntu_impish;
+ if (mem.eql(u8, rest, "jammy")) return .ubuntu_jammy;
+ if (mem.eql(u8, rest, "kinetic")) return .ubuntu_kinetic;
+ if (mem.eql(u8, rest, "lunar")) return .ubuntu_lunar;
+ }
+ }
+ return null;
+}
+
+fn detectLSBRelease(fs: Filesystem) ?Tag {
+ var buf: [MAX_BYTES]u8 = undefined;
+ const data = fs.readFile("/etc/lsb-release", &buf) orelse return null;
+
+ return scanForLSBRelease(data);
+}
+
+fn scanForRedHat(buf: []const u8) Tag {
+ if (mem.startsWith(u8, buf, "Fedora release")) return .fedora;
+ if (mem.startsWith(u8, buf, "Red Hat Enterprise Linux") or mem.startsWith(u8, buf, "CentOS") or mem.startsWith(u8, buf, "Scientific Linux")) {
+ if (mem.indexOfPos(u8, buf, 0, "release 7") != null) return .rhel7;
+ if (mem.indexOfPos(u8, buf, 0, "release 6") != null) return .rhel6;
+ if (mem.indexOfPos(u8, buf, 0, "release 5") != null) return .rhel5;
+ }
+
+ return .unknown;
+}
+
+fn detectRedhat(fs: Filesystem) ?Tag {
+ var buf: [MAX_BYTES]u8 = undefined;
+ const data = fs.readFile("/etc/redhat-release", &buf) orelse return null;
+ return scanForRedHat(data);
+}
+
+fn scanForDebian(buf: []const u8) Tag {
+ var it = mem.splitScalar(u8, buf, '.');
+ if (std.fmt.parseInt(u8, it.next().?, 10)) |major| {
+ return switch (major) {
+ 5 => .debian_lenny,
+ 6 => .debian_squeeze,
+ 7 => .debian_wheezy,
+ 8 => .debian_jessie,
+ 9 => .debian_stretch,
+ 10 => .debian_buster,
+ 11 => .debian_bullseye,
+ 12 => .debian_bookworm,
+ 13 => .debian_trixie,
+ else => .unknown,
+ };
+ } else |_| {}
+
+ it = mem.splitScalar(u8, buf, '\n');
+ const name = it.next().?;
+ if (mem.eql(u8, name, "squeeze/sid")) return .debian_squeeze;
+ if (mem.eql(u8, name, "wheezy/sid")) return .debian_wheezy;
+ if (mem.eql(u8, name, "jessie/sid")) return .debian_jessie;
+ if (mem.eql(u8, name, "stretch/sid")) return .debian_stretch;
+ if (mem.eql(u8, name, "buster/sid")) return .debian_buster;
+ if (mem.eql(u8, name, "bullseye/sid")) return .debian_bullseye;
+ if (mem.eql(u8, name, "bookworm/sid")) return .debian_bookworm;
+
+ return .unknown;
+}
+
+fn detectDebian(fs: Filesystem) ?Tag {
+ var buf: [MAX_BYTES]u8 = undefined;
+ const data = fs.readFile("/etc/debian_version", &buf) orelse return null;
+ return scanForDebian(data);
+}
+
+pub fn detect(target: std.Target, fs: Filesystem) Tag {
+ if (target.os.tag != .linux) return .unknown;
+
+ if (detectOsRelease(fs)) |tag| return tag;
+ if (detectLSBRelease(fs)) |tag| return tag;
+ if (detectRedhat(fs)) |tag| return tag;
+ if (detectDebian(fs)) |tag| return tag;
+
+ if (fs.exists("/etc/gentoo-release")) return .gentoo;
+
+ return .unknown;
+}
+
+test scanForDebian {
+ try std.testing.expectEqual(Tag.debian_squeeze, scanForDebian("squeeze/sid"));
+ try std.testing.expectEqual(Tag.debian_bullseye, scanForDebian("11.1.2"));
+ try std.testing.expectEqual(Tag.unknown, scanForDebian("None"));
+ try std.testing.expectEqual(Tag.unknown, scanForDebian(""));
+}
+
+test scanForRedHat {
+ try std.testing.expectEqual(Tag.fedora, scanForRedHat("Fedora release 7"));
+ try std.testing.expectEqual(Tag.rhel7, scanForRedHat("Red Hat Enterprise Linux release 7"));
+ try std.testing.expectEqual(Tag.rhel5, scanForRedHat("CentOS release 5"));
+ try std.testing.expectEqual(Tag.unknown, scanForRedHat("CentOS release 4"));
+ try std.testing.expectEqual(Tag.unknown, scanForRedHat(""));
+}
+
+test scanForLSBRelease {
+ const text =
+ \\DISTRIB_ID=Ubuntu
+ \\DISTRIB_RELEASE=20.04
+ \\DISTRIB_CODENAME=focal
+ \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
+ \\
+ ;
+ try std.testing.expectEqual(Tag.ubuntu_focal, scanForLSBRelease(text).?);
+}
+
+test scanForOsRelease {
+ const text =
+ \\NAME="Alpine Linux"
+ \\ID=alpine
+ \\VERSION_ID=3.18.2
+ \\PRETTY_NAME="Alpine Linux v3.18"
+ \\HOME_URL="https://alpinelinux.org/"
+ \\BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
+ \\
+ ;
+ try std.testing.expectEqual(Tag.alpine, scanForOsRelease(text).?);
+}
deps/aro/Driver/Filesystem.zig
@@ -0,0 +1,242 @@
+const std = @import("std");
+const mem = std.mem;
+const builtin = @import("builtin");
+const system_defaults = @import("system_defaults");
+const is_windows = builtin.os.tag == .windows;
+
+fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 {
+ @setCold(true);
+ for (entries) |entry| {
+ if (mem.eql(u8, entry.path, path)) {
+ const len = @min(entry.contents.len, buf.len);
+ @memcpy(buf[0..len], entry.contents[0..len]);
+ return buf[0..len];
+ }
+ }
+ return null;
+}
+
+fn findProgramByNameFake(entries: []const Filesystem.Entry, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+ @setCold(true);
+ if (mem.indexOfScalar(u8, name, '/') != null) {
+ @memcpy(buf[0..name.len], name);
+ return buf[0..name.len];
+ }
+ const path_env = path orelse return null;
+ var fib = std.heap.FixedBufferAllocator.init(buf);
+
+ var it = mem.tokenizeScalar(u8, path_env, system_defaults.path_sep);
+ while (it.next()) |path_dir| {
+ defer fib.reset();
+ const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
+ if (canExecuteFake(entries, full_path)) return full_path;
+ }
+
+ return null;
+}
+
+fn canExecuteFake(entries: []const Filesystem.Entry, path: []const u8) bool {
+ @setCold(true);
+ for (entries) |entry| {
+ if (mem.eql(u8, entry.path, path)) {
+ return entry.executable;
+ }
+ }
+ return false;
+}
+
+fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool {
+ @setCold(true);
+ var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var fib = std.heap.FixedBufferAllocator.init(&buf);
+ const resolved = std.fs.path.resolvePosix(fib.allocator(), &.{path}) catch return false;
+ for (entries) |entry| {
+ if (mem.eql(u8, entry.path, resolved)) return true;
+ }
+ return false;
+}
+
+fn canExecutePosix(path: []const u8) bool {
+ std.os.access(path, std.os.X_OK) catch return false;
+ // Todo: ensure path is not a directory
+ return true;
+}
+
+/// TODO
+fn canExecuteWindows(path: []const u8) bool {
+ _ = path;
+ return true;
+}
+
+/// TODO
+fn findProgramByNameWindows(allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+ _ = path;
+ _ = buf;
+ _ = name;
+ _ = allocator;
+ return null;
+}
+
+/// TODO: does WASI need special handling?
+fn findProgramByNamePosix(name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+ if (mem.indexOfScalar(u8, name, '/') != null) {
+ @memcpy(buf[0..name.len], name);
+ return buf[0..name.len];
+ }
+ const path_env = path orelse return null;
+ var fib = std.heap.FixedBufferAllocator.init(buf);
+
+ var it = mem.tokenizeScalar(u8, path_env, system_defaults.path_sep);
+ while (it.next()) |path_dir| {
+ defer fib.reset();
+ const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
+ if (canExecutePosix(full_path)) return full_path;
+ }
+
+ return null;
+}
+
+pub const Filesystem = union(enum) {
+ real: void,
+ fake: []const Entry,
+
+ const Entry = struct {
+ path: []const u8,
+ contents: []const u8 = "",
+ executable: bool = false,
+ };
+
+ const FakeDir = struct {
+ entries: []const Entry,
+ path: []const u8,
+
+ fn iterate(self: FakeDir) FakeDir.Iterator {
+ return .{
+ .entries = self.entries,
+ .base = self.path,
+ };
+ }
+
+ const Iterator = struct {
+ entries: []const Entry,
+ base: []const u8,
+ i: usize = 0,
+
+ const Self = @This();
+
+ fn next(self: *@This()) !?std.fs.IterableDir.Entry {
+ while (self.i < self.entries.len) {
+ const entry = self.entries[self.i];
+ self.i += 1;
+ if (entry.path.len == self.base.len) continue;
+ if (std.mem.startsWith(u8, entry.path, self.base)) {
+ const remaining = entry.path[self.base.len + 1 ..];
+ if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue;
+ const extension = std.fs.path.extension(remaining);
+ const kind: std.fs.IterableDir.Entry.Kind = if (extension.len == 0) .directory else .file;
+ return .{ .name = remaining, .kind = kind };
+ }
+ }
+ return null;
+ }
+ };
+ };
+
+ const IterableDir = union(enum) {
+ dir: std.fs.IterableDir,
+ fake: FakeDir,
+
+ pub fn iterate(self: IterableDir) Iterator {
+ return switch (self) {
+ .dir => |dir| .{ .iterator = dir.iterate() },
+ .fake => |fake| .{ .fake = fake.iterate() },
+ };
+ }
+
+ pub fn close(self: *IterableDir) void {
+ switch (self.*) {
+ .dir => |*d| d.close(),
+ .fake => {},
+ }
+ }
+ };
+
+ const Iterator = union(enum) {
+ iterator: std.fs.IterableDir.Iterator,
+ fake: FakeDir.Iterator,
+
+ pub fn next(self: *Iterator) std.fs.IterableDir.Iterator.Error!?std.fs.IterableDir.Entry {
+ return switch (self.*) {
+ .iterator => |*it| it.next(),
+ .fake => |*it| it.next(),
+ };
+ }
+ };
+
+ pub fn exists(fs: Filesystem, path: []const u8) bool {
+ switch (fs) {
+ .real => {
+ std.os.access(path, std.os.F_OK) catch return false;
+ return true;
+ },
+ .fake => |paths| return existsFake(paths, path),
+ }
+ }
+
+ pub fn joinedExists(fs: Filesystem, parts: []const []const u8) bool {
+ var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var fib = std.heap.FixedBufferAllocator.init(&buf);
+ const joined = std.fs.path.join(fib.allocator(), parts) catch return false;
+ return fs.exists(joined);
+ }
+
+ pub fn canExecute(fs: Filesystem, path: []const u8) bool {
+ return switch (fs) {
+ .real => if (is_windows) canExecuteWindows(path) else canExecutePosix(path),
+ .fake => |entries| canExecuteFake(entries, path),
+ };
+ }
+
+ /// Search for an executable named `name` using platform-specific logic
+ /// If it's found, write the full path to `buf` and return a slice of it
+ /// Otherwise retun null
+ pub fn findProgramByName(fs: Filesystem, allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+ std.debug.assert(name.len > 0);
+ return switch (fs) {
+ .real => if (is_windows) findProgramByNameWindows(allocator, name, path, buf) else findProgramByNamePosix(name, path, buf),
+ .fake => |entries| findProgramByNameFake(entries, name, path, buf),
+ };
+ }
+
+ /// Read the file at `path` into `buf`.
+ /// Returns null if any errors are encountered
+ /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned
+ pub fn readFile(fs: Filesystem, path: []const u8, buf: []u8) ?[]const u8 {
+ return switch (fs) {
+ .real => {
+ const file = std.fs.cwd().openFile(path, .{}) catch return null;
+ defer file.close();
+
+ const bytes_read = file.readAll(buf) catch return null;
+ return buf[0..bytes_read];
+ },
+ .fake => |entries| readFileFake(entries, path, buf),
+ };
+ }
+
+ pub fn openIterableDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!IterableDir {
+ return switch (fs) {
+ .real => .{ .dir = try std.fs.cwd().openIterableDir(dir_name, .{ .access_sub_paths = false }) },
+ .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },
+ };
+ }
+};
+
+test "Fake filesystem" {
+ const fs: Filesystem = .{ .fake = &.{
+ .{ .path = "/usr/bin" },
+ } };
+ try std.testing.expect(fs.exists("/usr/bin"));
+ try std.testing.expect(fs.exists("/usr/bin/foo/.."));
+ try std.testing.expect(!fs.exists("/usr/bin/bar"));
+}
deps/aro/Driver/GCCDetector.zig
@@ -0,0 +1,610 @@
+const std = @import("std");
+const Toolchain = @import("../Toolchain.zig");
+const target_util = @import("../target.zig");
+const system_defaults = @import("system_defaults");
+const util = @import("../util.zig");
+const GCCVersion = @import("GCCVersion.zig");
+const Multilib = @import("Multilib.zig");
+const GCCDetector = @This();
+
+is_valid: bool = false,
+install_path: []const u8 = "",
+parent_lib_path: []const u8 = "",
+version: GCCVersion = .{},
+gcc_triple: []const u8 = "",
+selected: Multilib = .{},
+biarch_sibling: ?Multilib = null,
+
+pub fn deinit(self: *GCCDetector) void {
+ if (!self.is_valid) return;
+}
+
+pub fn appendToolPath(self: *const GCCDetector, tc: *Toolchain) !void {
+ if (!self.is_valid) return;
+ return tc.addPathFromComponents(&.{
+ self.parent_lib_path,
+ "..",
+ self.gcc_triple,
+ "bin",
+ }, .program);
+}
+
+fn addDefaultGCCPrefixes(prefixes: *PathPrefixes, tc: *const Toolchain) !void {
+ const sysroot = tc.getSysroot();
+ const target = tc.getTarget();
+ if (sysroot.len == 0 and target.os.tag == .linux and tc.filesystem.exists("/opt/rh")) {
+ prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-12/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-11/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-10/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-12/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-11/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-10/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-9/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-8/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-7/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-6/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-4/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-3/root/usr");
+ prefixes.appendAssumeCapacity("/opt/rh/devtoolset-2/root/usr");
+ }
+ if (sysroot.len == 0) {
+ prefixes.appendAssumeCapacity("/usr");
+ } else {
+ var usr_path = try tc.arena.alloc(u8, 4 + sysroot.len);
+ @memcpy(usr_path[0..4], "/usr");
+ @memcpy(usr_path[4..], sysroot);
+ prefixes.appendAssumeCapacity(usr_path);
+ }
+}
+
+const PathPrefixes = std.BoundedArray([]const u8, 16);
+
+fn collectLibDirsAndTriples(
+ tc: *Toolchain,
+ lib_dirs: *PathPrefixes,
+ triple_aliases: *PathPrefixes,
+ biarch_libdirs: *PathPrefixes,
+ biarch_triple_aliases: *PathPrefixes,
+) !void {
+ const AArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const AArch64Triples: [4][]const u8 = .{ "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux" };
+ const AArch64beLibDirs: [1][]const u8 = .{"/lib"};
+ const AArch64beTriples: [2][]const u8 = .{ "aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu" };
+
+ const ARMLibDirs: [1][]const u8 = .{"/lib"};
+ const ARMTriples: [1][]const u8 = .{"arm-linux-gnueabi"};
+ const ARMHFTriples: [4][]const u8 = .{ "arm-linux-gnueabihf", "armv7hl-redhat-linux-gnueabi", "armv6hl-suse-linux-gnueabi", "armv7hl-suse-linux-gnueabi" };
+
+ const ARMebLibDirs: [1][]const u8 = .{"/lib"};
+ const ARMebTriples: [1][]const u8 = .{"armeb-linux-gnueabi"};
+ const ARMebHFTriples: [2][]const u8 = .{ "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi" };
+
+ const AVRLibDirs: [1][]const u8 = .{"/lib"};
+ const AVRTriples: [1][]const u8 = .{"avr"};
+
+ const CSKYLibDirs: [1][]const u8 = .{"/lib"};
+ const CSKYTriples: [3][]const u8 = .{ "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2" };
+
+ const X86_64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const X86_64Triples: [11][]const u8 = .{
+ "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",
+ "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",
+ "x86_64-redhat-linux", "x86_64-suse-linux",
+ "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
+ "x86_64-slackware-linux", "x86_64-unknown-linux",
+ "x86_64-amazon-linux",
+ };
+ const X32Triples: [2][]const u8 = .{ "x86_64-linux-gnux32", "x86_64-pc-linux-gnux32" };
+ const X32LibDirs: [2][]const u8 = .{ "/libx32", "/lib" };
+ const X86LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+ const X86Triples: [9][]const u8 = .{
+ "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu",
+ "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux",
+ "i586-suse-linux", "i686-montavista-linux", "i686-gnu",
+ };
+
+ const LoongArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const LoongArch64Triples: [2][]const u8 = .{ "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu" };
+
+ const M68kLibDirs: [1][]const u8 = .{"/lib"};
+ const M68kTriples: [3][]const u8 = .{ "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux" };
+
+ const MIPSLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
+ const MIPSTriples: [5][]const u8 = .{
+ "mips-linux-gnu", "mips-mti-linux",
+ "mips-mti-linux-gnu", "mips-img-linux-gnu",
+ "mipsisa32r6-linux-gnu",
+ };
+ const MIPSELLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
+ const MIPSELTriples: [3][]const u8 = .{ "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu" };
+
+ const MIPS64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const MIPS64Triples: [6][]const u8 = .{
+ "mips64-linux-gnu", "mips-mti-linux-gnu",
+ "mips-img-linux-gnu", "mips64-linux-gnuabi64",
+ "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64",
+ };
+ const MIPS64ELLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const MIPS64ELTriples: [6][]const u8 = .{
+ "mips64el-linux-gnu", "mips-mti-linux-gnu",
+ "mips-img-linux-gnu", "mips64el-linux-gnuabi64",
+ "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64",
+ };
+
+ const MIPSN32LibDirs: [1][]const u8 = .{"/lib32"};
+ const MIPSN32Triples: [2][]const u8 = .{ "mips64-linux-gnuabin32", "mipsisa64r6-linux-gnuabin32" };
+ const MIPSN32ELLibDirs: [1][]const u8 = .{"/lib32"};
+ const MIPSN32ELTriples: [2][]const u8 = .{ "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32" };
+
+ const MSP430LibDirs: [1][]const u8 = .{"/lib"};
+ const MSP430Triples: [1][]const u8 = .{"msp430-elf"};
+
+ const PPCLibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+ const PPCTriples: [5][]const u8 = .{
+ "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
+ // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
+ // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".
+ "powerpc64-suse-linux", "powerpc-montavista-linuxspe",
+ };
+ const PPCLELibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+ const PPCLETriples: [3][]const u8 = .{ "powerpcle-linux-gnu", "powerpcle-unknown-linux-gnu", "powerpcle-linux-musl" };
+
+ const PPC64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const PPC64Triples: [4][]const u8 = .{
+ "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
+ "powerpc64-suse-linux", "ppc64-redhat-linux",
+ };
+ const PPC64LELibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const PPC64LETriples: [5][]const u8 = .{
+ "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
+ "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux",
+ "ppc64le-redhat-linux",
+ };
+
+ const RISCV32LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+ const RISCV32Triples: [3][]const u8 = .{ "riscv32-unknown-linux-gnu", "riscv32-linux-gnu", "riscv32-unknown-elf" };
+ const RISCV64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const RISCV64Triples: [3][]const u8 = .{
+ "riscv64-unknown-linux-gnu",
+ "riscv64-linux-gnu",
+ "riscv64-unknown-elf",
+ };
+
+ const SPARCv8LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+ const SPARCv8Triples: [2][]const u8 = .{ "sparc-linux-gnu", "sparcv8-linux-gnu" };
+ const SPARCv9LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const SPARCv9Triples: [2][]const u8 = .{ "sparc64-linux-gnu", "sparcv9-linux-gnu" };
+
+ const SystemZLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+ const SystemZTriples: [5][]const u8 = .{
+ "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
+ "s390x-suse-linux", "s390x-redhat-linux",
+ };
+ const target = tc.getTarget();
+ if (target.os.tag == .solaris) {
+ // TODO
+ return;
+ }
+ if (target.isAndroid()) {
+ const AArch64AndroidTriples: [1][]const u8 = .{"aarch64-linux-android"};
+ const ARMAndroidTriples: [1][]const u8 = .{"arm-linux-androideabi"};
+ const MIPSELAndroidTriples: [1][]const u8 = .{"mipsel-linux-android"};
+ const MIPS64ELAndroidTriples: [1][]const u8 = .{"mips64el-linux-android"};
+ const X86AndroidTriples: [1][]const u8 = .{"i686-linux-android"};
+ const X86_64AndroidTriples: [1][]const u8 = .{"x86_64-linux-android"};
+
+ switch (target.cpu.arch) {
+ .aarch64 => {
+ lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&AArch64AndroidTriples);
+ },
+ .arm,
+ .thumb,
+ => {
+ lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&ARMAndroidTriples);
+ },
+ .mipsel => {
+ lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
+ },
+ .mips64el => {
+ lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
+ },
+ .x86_64 => {
+ lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
+ },
+ .x86 => {
+ lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
+ },
+ else => {},
+ }
+ return;
+ }
+ switch (target.cpu.arch) {
+ .aarch64 => {
+ lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&AArch64LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
+ },
+ .aarch64_be => {
+ lib_dirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
+ },
+ .arm, .thumb => {
+ lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
+ if (target.abi == .gnueabihf) {
+ triple_aliases.appendSliceAssumeCapacity(&ARMHFTriples);
+ } else {
+ triple_aliases.appendSliceAssumeCapacity(&ARMTriples);
+ }
+ },
+ .armeb, .thumbeb => {
+ lib_dirs.appendSliceAssumeCapacity(&ARMebLibDirs);
+ if (target.abi == .gnueabihf) {
+ triple_aliases.appendSliceAssumeCapacity(&ARMebHFTriples);
+ } else {
+ triple_aliases.appendSliceAssumeCapacity(&ARMebTriples);
+ }
+ },
+ .avr => {
+ lib_dirs.appendSliceAssumeCapacity(&AVRLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&AVRTriples);
+ },
+ .csky => {
+ lib_dirs.appendSliceAssumeCapacity(&CSKYLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&CSKYTriples);
+ },
+ .x86_64 => {
+ if (target.abi == .gnux32 or target.abi == .muslx32) {
+ lib_dirs.appendSliceAssumeCapacity(&X32LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&X32Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
+ } else {
+ lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
+ }
+ biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&X86Triples);
+ },
+ .x86 => {
+ lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
+ // MCU toolchain is 32 bit only and its triple alias is TargetTriple
+ // itself, which will be appended below.
+ if (target.os.tag != .elfiamcu) {
+ triple_aliases.appendSliceAssumeCapacity(&X86Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
+ }
+ },
+ .loongarch64 => {
+ lib_dirs.appendSliceAssumeCapacity(&LoongArch64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&LoongArch64Triples);
+ },
+ .m68k => {
+ lib_dirs.appendSliceAssumeCapacity(&M68kLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&M68kTriples);
+ },
+ .mips => {
+ lib_dirs.appendSliceAssumeCapacity(&MIPSLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
+ },
+ .mipsel => {
+ lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
+ triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
+ },
+ .mips64 => {
+ lib_dirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPSLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
+ },
+ .mips64el => {
+ lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+ },
+ .msp430 => {
+ lib_dirs.appendSliceAssumeCapacity(&MSP430LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&MSP430Triples);
+ },
+ .powerpc => {
+ lib_dirs.appendSliceAssumeCapacity(&PPCLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&PPC64LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
+ },
+ .powerpcle => {
+ lib_dirs.appendSliceAssumeCapacity(&PPCLELibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
+ },
+ .powerpc64 => {
+ lib_dirs.appendSliceAssumeCapacity(&PPC64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&PPCLibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
+ },
+ .powerpc64le => {
+ lib_dirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
+ biarch_libdirs.appendSliceAssumeCapacity(&PPCLELibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
+ },
+ .riscv32 => {
+ lib_dirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
+ },
+ .riscv64 => {
+ lib_dirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
+ },
+ .sparc, .sparcel => {
+ lib_dirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
+ },
+ .sparc64 => {
+ lib_dirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
+ biarch_libdirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
+ biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
+ },
+ .s390x => {
+ lib_dirs.appendSliceAssumeCapacity(&SystemZLibDirs);
+ triple_aliases.appendSliceAssumeCapacity(&SystemZTriples);
+ },
+ else => {},
+ }
+}
+
+pub fn discover(self: *GCCDetector, tc: *Toolchain) !void {
+ var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+
+ const target = tc.getTarget();
+ const biarch_variant_target = if (target.ptrBitWidth() == 32) target_util.get64BitArchVariant(target) else target_util.get32BitArchVariant(target);
+
+ var candidate_lib_dirs: PathPrefixes = .{};
+ var candidate_biarch_lib_dirs: PathPrefixes = .{};
+ var candidate_triple_aliases: PathPrefixes = .{};
+ var candidate_biarch_triple_aliases: PathPrefixes = .{};
+ try collectLibDirsAndTriples(tc, &candidate_lib_dirs, &candidate_biarch_lib_dirs, &candidate_triple_aliases, &candidate_biarch_triple_aliases);
+
+ var target_buf: [64]u8 = undefined;
+ const triple_str = target_util.toLLVMTriple(target, &target_buf);
+ candidate_triple_aliases.appendAssumeCapacity(triple_str);
+
+ // Also include the multiarch variant if it's different.
+ var biarch_buf: [64]u8 = undefined;
+ if (biarch_variant_target) |biarch_target| {
+ const biarch_triple_str = target_util.toLLVMTriple(biarch_target, &biarch_buf);
+ if (!std.mem.eql(u8, biarch_triple_str, triple_str)) {
+ candidate_triple_aliases.appendAssumeCapacity(biarch_triple_str);
+ }
+ }
+
+ var prefixes: PathPrefixes = .{};
+ const gcc_toolchain_dir = gccToolchainDir(tc);
+ if (gcc_toolchain_dir.len != 0) {
+ const adjusted = if (gcc_toolchain_dir[gcc_toolchain_dir.len - 1] == '/')
+ gcc_toolchain_dir[0 .. gcc_toolchain_dir.len - 1]
+ else
+ gcc_toolchain_dir;
+ prefixes.appendAssumeCapacity(adjusted);
+ } else {
+ const sysroot = tc.getSysroot();
+ if (sysroot.len > 0) {
+ prefixes.appendAssumeCapacity(sysroot);
+ try addDefaultGCCPrefixes(&prefixes, tc);
+ }
+
+ if (sysroot.len == 0) {
+ try addDefaultGCCPrefixes(&prefixes, tc);
+ }
+ // TODO: Special-case handling for Gentoo
+ }
+
+ const v0 = GCCVersion.parse("0.0.0");
+ for (prefixes.constSlice()) |prefix| {
+ if (!tc.filesystem.exists(prefix)) continue;
+
+ for (candidate_lib_dirs.constSlice()) |suffix| {
+ defer fib.reset();
+ const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
+ if (!tc.filesystem.exists(lib_dir)) continue;
+
+ const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
+ const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
+
+ try self.scanLibDirForGCCTriple(tc, target, lib_dir, triple_str, false, gcc_dir_exists, gcc_cross_dir_exists);
+ for (candidate_triple_aliases.constSlice()) |candidate| {
+ try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, false, gcc_dir_exists, gcc_cross_dir_exists);
+ }
+ }
+ for (candidate_biarch_lib_dirs.constSlice()) |suffix| {
+ const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
+ if (!tc.filesystem.exists(lib_dir)) continue;
+
+ const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
+ const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
+ for (candidate_biarch_triple_aliases.constSlice()) |candidate| {
+ try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, true, gcc_dir_exists, gcc_cross_dir_exists);
+ }
+ }
+ if (self.version.order(v0) == .gt) break;
+ }
+}
+
+fn findBiarchMultilibs(tc: *const Toolchain, result: *Multilib.Detected, target: std.Target, path: [2][]const u8, needs_biarch_suffix: bool) !bool {
+ const suff64 = if (target.os.tag == .solaris) switch (target.cpu.arch) {
+ .x86, .x86_64 => "/amd64",
+ .sparc => "/sparcv9",
+ else => "/64",
+ } else "/64";
+
+ const alt_64 = Multilib.init(suff64, suff64, &.{ "-m32", "+m64", "-mx32" });
+ const alt_32 = Multilib.init("/32", "/32", &.{ "+m32", "-m64", "-mx32" });
+ const alt_x32 = Multilib.init("/x32", "/x32", &.{ "-m32", "-m64", "+mx32" });
+
+ const multilib_filter = Multilib.Filter{
+ .base = path,
+ .file = if (target.os.tag == .elfiamcu) "libgcc.a" else "crtbegin.o",
+ };
+
+ const Want = enum {
+ want32,
+ want64,
+ wantx32,
+ };
+ const is_x32 = target.abi == .gnux32 or target.abi == .muslx32;
+ const target_ptr_width = target.ptrBitWidth();
+ const want: Want = if (target_ptr_width == 32 and multilib_filter.exists(alt_32, tc.filesystem))
+ .want64
+ else if (target_ptr_width == 64 and is_x32 and multilib_filter.exists(alt_x32, tc.filesystem))
+ .want64
+ else if (target_ptr_width == 64 and !is_x32 and multilib_filter.exists(alt_64, tc.filesystem))
+ .want32
+ else if (target_ptr_width == 32)
+ if (needs_biarch_suffix) .want64 else .want32
+ else if (is_x32)
+ if (needs_biarch_suffix) .want64 else .wantx32
+ else if (needs_biarch_suffix) .want32 else .want64;
+
+ const default = switch (want) {
+ .want32 => Multilib.init("", "", &.{ "+m32", "-m64", "-mx32" }),
+ .want64 => Multilib.init("", "", &.{ "-m32", "+m64", "-mx32" }),
+ .wantx32 => Multilib.init("", "", &.{ "-m32", "-m64", "+mx32" }),
+ };
+ result.multilibs.appendSliceAssumeCapacity(&.{
+ default,
+ alt_64,
+ alt_32,
+ alt_x32,
+ });
+ result.filter(multilib_filter, tc.filesystem);
+ var flags: Multilib.Flags = .{};
+ flags.appendAssumeCapacity(if (target_ptr_width == 64 and !is_x32) "+m64" else "-m64");
+ flags.appendAssumeCapacity(if (target_ptr_width == 32) "+m32" else "-m32");
+ flags.appendAssumeCapacity(if (target_ptr_width == 64 and is_x32) "+mx32" else "-mx32");
+
+ return result.select(flags);
+}
+
+fn scanGCCForMultilibs(self: *GCCDetector, tc: *const Toolchain, target: std.Target, path: [2][]const u8, needs_biarch_suffix: bool) !bool {
+ var detected: Multilib.Detected = .{};
+ if (target.cpu.arch == .csky) {
+ // TODO
+ } else if (target.cpu.arch.isMIPS()) {
+ // TODO
+ } else if (target.cpu.arch.isRISCV()) {
+ // TODO
+ } else if (target.cpu.arch == .msp430) {
+ // TODO
+ } else if (target.cpu.arch == .avr) {
+ // No multilibs
+ } else if (!try findBiarchMultilibs(tc, &detected, target, path, needs_biarch_suffix)) {
+ return false;
+ }
+ self.selected = detected.selected;
+ self.biarch_sibling = detected.biarch_sibling;
+ return true;
+}
+
+fn scanLibDirForGCCTriple(
+ self: *GCCDetector,
+ tc: *const Toolchain,
+ target: std.Target,
+ lib_dir: []const u8,
+ candidate_triple: []const u8,
+ needs_biarch_suffix: bool,
+ gcc_dir_exists: bool,
+ gcc_cross_dir_exists: bool,
+) !void {
+ var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+ for (0..2) |i| {
+ if (i == 0 and !gcc_dir_exists) continue;
+ if (i == 1 and !gcc_cross_dir_exists) continue;
+ defer fib.reset();
+
+ const base: []const u8 = if (i == 0) "gcc" else "gcc-cross";
+ var lib_suffix_buf: [64]u8 = undefined;
+ var suffix_buf_fib = std.heap.FixedBufferAllocator.init(&lib_suffix_buf);
+ const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue;
+
+ const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue;
+ var parent_dir = tc.filesystem.openIterableDir(dir_name) catch continue;
+ defer parent_dir.close();
+
+ var it = parent_dir.iterate();
+ while (it.next() catch continue) |entry| {
+ if (entry.kind != .directory) continue;
+
+ const version_text = entry.name;
+ const candidate_version = GCCVersion.parse(version_text);
+ if (candidate_version.major != -1) {
+ // TODO: cache path so we're not repeatedly scanning
+ }
+ if (candidate_version.isLessThan(4, 1, 1, "")) continue;
+ switch (candidate_version.order(self.version)) {
+ .lt, .eq => continue,
+ .gt => {},
+ }
+
+ if (!try self.scanGCCForMultilibs(tc, target, .{ dir_name, version_text }, needs_biarch_suffix)) continue;
+
+ self.version = candidate_version;
+ self.gcc_triple = try tc.arena.dupe(u8, candidate_triple);
+ self.install_path = try std.fs.path.join(tc.arena, &.{ lib_dir, lib_suffix, version_text });
+ self.parent_lib_path = try std.fs.path.join(tc.arena, &.{ self.install_path, "..", "..", ".." });
+ self.is_valid = true;
+ }
+ }
+}
+
+fn gccToolchainDir(tc: *const Toolchain) []const u8 {
+ const sysroot = tc.getSysroot();
+ if (sysroot.len != 0) return "";
+ return system_defaults.gcc_install_prefix;
+}
deps/aro/Driver/GCCVersion.zig
@@ -0,0 +1,122 @@
+const std = @import("std");
+const mem = std.mem;
+const Order = std.math.Order;
+
+const GCCVersion = @This();
+
+/// Raw version number text
+raw: []const u8 = "",
+
+/// -1 indicates not present
+major: i32 = -1,
+/// -1 indicates not present
+minor: i32 = -1,
+/// -1 indicates not present
+patch: i32 = -1,
+
+/// Text of parsed major version number
+major_str: []const u8 = "",
+/// Text of parsed major + minor version number
+minor_str: []const u8 = "",
+
+/// Patch number suffix
+suffix: []const u8 = "",
+
+/// This orders versions according to the preferred usage order, not a notion of release-time ordering
+/// Higher version numbers are preferred, but nonexistent minor/patch/suffix is preferred to one that does exist
+/// e.g. `4.1` is preferred over `4.0` but `4` is preferred over both `4.0` and `4.1`
+pub fn isLessThan(self: GCCVersion, rhs_major: i32, rhs_minor: i32, rhs_patch: i32, rhs_suffix: []const u8) bool {
+ if (self.major != rhs_major) {
+ return self.major < rhs_major;
+ }
+ if (self.minor != rhs_minor) {
+ if (rhs_minor == -1) return true;
+ if (self.minor == -1) return false;
+ return self.minor < rhs_minor;
+ }
+ if (self.patch != rhs_patch) {
+ if (rhs_patch == -1) return true;
+ if (self.patch == -1) return false;
+ return self.patch < rhs_patch;
+ }
+ if (!mem.eql(u8, self.suffix, rhs_suffix)) {
+ if (rhs_suffix.len == 0) return true;
+ if (self.suffix.len == 0) return false;
+ return switch (std.mem.order(u8, self.suffix, rhs_suffix)) {
+ .lt => true,
+ .eq => unreachable,
+ .gt => false,
+ };
+ }
+ return false;
+}
+
+/// Strings in the returned GCCVersion struct have the same lifetime as `text`
+pub fn parse(text: []const u8) GCCVersion {
+ const bad = GCCVersion{ .major = -1 };
+ var good = bad;
+
+ var it = mem.splitScalar(u8, text, '.');
+ const first = it.next().?;
+ const second = it.next() orelse "";
+ const rest = it.next() orelse "";
+
+ good.major = std.fmt.parseInt(i32, first, 10) catch return bad;
+ if (good.major < 0) return bad;
+ good.major_str = first;
+
+ if (second.len == 0) return good;
+ var minor_str = second;
+
+ if (rest.len == 0) {
+ const end = mem.indexOfNone(u8, minor_str, "0123456789") orelse minor_str.len;
+ if (end > 0) {
+ good.suffix = minor_str[end..];
+ minor_str = minor_str[0..end];
+ }
+ }
+ good.minor = std.fmt.parseInt(i32, minor_str, 10) catch return bad;
+ if (good.minor < 0) return bad;
+ good.minor_str = minor_str;
+
+ if (rest.len > 0) {
+ const end = mem.indexOfNone(u8, rest, "0123456789") orelse rest.len;
+ if (end > 0) {
+ const patch_num_text = rest[0..end];
+ good.patch = std.fmt.parseInt(i32, patch_num_text, 10) catch return bad;
+ if (good.patch < 0) return bad;
+ good.suffix = rest[end..];
+ }
+ }
+
+ return good;
+}
+
+pub fn order(a: GCCVersion, b: GCCVersion) Order {
+ if (a.isLessThan(b.major, b.minor, b.patch, b.suffix)) return .lt;
+ if (b.isLessThan(a.major, a.minor, a.patch, a.suffix)) return .gt;
+ return .eq;
+}
+
+test parse {
+ const versions = [10]GCCVersion{
+ parse("5"),
+ parse("4"),
+ parse("4.2"),
+ parse("4.0"),
+ parse("4.0-patched"),
+ parse("4.0.2"),
+ parse("4.0.1"),
+ parse("4.0.1-patched"),
+ parse("4.0.0"),
+ parse("4.0.0-patched"),
+ };
+
+ for (versions[0 .. versions.len - 1], versions[1..versions.len]) |first, second| {
+ try std.testing.expectEqual(Order.eq, first.order(first));
+ try std.testing.expectEqual(Order.gt, first.order(second));
+ try std.testing.expectEqual(Order.lt, second.order(first));
+ }
+ const last = versions[versions.len - 1];
+ try std.testing.expectEqual(Order.eq, last.order(last));
+}
deps/aro/Driver/Multilib.zig
@@ -0,0 +1,72 @@
+const std = @import("std");
+const util = @import("../util.zig");
+const Filesystem = @import("Filesystem.zig").Filesystem;
+
+pub const Flags = std.BoundedArray([]const u8, 6);
+
+/// Large enough for GCCDetector for Linux; may need to be increased to support other toolchains.
+const max_multilibs = 4;
+
+const MultilibArray = std.BoundedArray(Multilib, max_multilibs);
+
+pub const Detected = struct {
+ multilibs: MultilibArray = .{},
+ selected: Multilib = .{},
+ biarch_sibling: ?Multilib = null,
+
+ pub fn filter(self: *Detected, multilib_filter: Filter, fs: Filesystem) void {
+ var found_count: usize = 0;
+ for (self.multilibs.constSlice()) |multilib| {
+ if (multilib_filter.exists(multilib, fs)) {
+ self.multilibs.set(found_count, multilib);
+ found_count += 1;
+ }
+ }
+ self.multilibs.resize(found_count) catch unreachable;
+ }
+
+ pub fn select(self: *Detected, flags: Flags) !bool {
+ var filtered: MultilibArray = .{};
+ for (self.multilibs.constSlice()) |multilib| {
+ for (multilib.flags.constSlice()) |multilib_flag| {
+ const matched = for (flags.constSlice()) |arg_flag| {
+ if (std.mem.eql(u8, arg_flag[1..], multilib_flag[1..])) break arg_flag;
+ } else multilib_flag;
+ if (matched[0] != multilib_flag[0]) break;
+ } else {
+ filtered.appendAssumeCapacity(multilib);
+ }
+ }
+ if (filtered.len == 0) return false;
+ if (filtered.len == 1) {
+ self.selected = filtered.get(0);
+ return true;
+ }
+ return error.TooManyMultilibs;
+ }
+};
+
+pub const Filter = struct {
+ base: [2][]const u8,
+ file: []const u8,
+ pub fn exists(self: Filter, m: Multilib, fs: Filesystem) bool {
+ return fs.joinedExists(&.{ self.base[0], self.base[1], m.gcc_suffix, self.file });
+ }
+};
+
+const Multilib = @This();
+
+gcc_suffix: []const u8 = "",
+os_suffix: []const u8 = "",
+include_suffix: []const u8 = "",
+flags: Flags = .{},
+priority: u32 = 0,
+
+pub fn init(gcc_suffix: []const u8, os_suffix: []const u8, flags: []const []const u8) Multilib {
+ var self: Multilib = .{
+ .gcc_suffix = gcc_suffix,
+ .os_suffix = os_suffix,
+ };
+ self.flags.appendSliceAssumeCapacity(flags);
+ return self;
+}
deps/aro/object/Elf.zig
@@ -0,0 +1,377 @@
+const std = @import("std");
+const Compilation = @import("../Compilation.zig");
+const Object = @import("../Object.zig");
+
+const Elf = @This();
+
+const Section = struct {
+ data: std.ArrayList(u8),
+ relocations: std.ArrayListUnmanaged(Relocation) = .{},
+ flags: u64,
+ type: u32,
+ index: u16 = undefined,
+};
+
+const Symbol = struct {
+ section: ?*Section,
+ size: u64,
+ offset: u64,
+ index: u16 = undefined,
+ info: u8,
+};
+
+const Relocation = packed struct {
+ symbol: *Symbol,
+ addend: i64,
+ offset: u48,
+ type: u8,
+};
+
+const additional_sections = 3; // null section, strtab, symtab
+const strtab_index = 1;
+const symtab_index = 2;
+const strtab_default = "\x00.strtab\x00.symtab\x00";
+const strtab_name = 1;
+const symtab_name = "\x00.strtab\x00".len;
+
+obj: Object,
+/// The keys are owned by the Codegen.tree
+sections: std.StringHashMapUnmanaged(*Section) = .{},
+local_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
+global_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
+unnamed_symbol_mangle: u32 = 0,
+strtab_len: u64 = strtab_default.len,
+arena: std.heap.ArenaAllocator,
+
+pub fn create(comp: *Compilation) !*Object {
+ const elf = try comp.gpa.create(Elf);
+ elf.* = .{
+ .obj = .{ .format = .elf, .comp = comp },
+ .arena = std.heap.ArenaAllocator.init(comp.gpa),
+ };
+ return &elf.obj;
+}
+
+pub fn deinit(elf: *Elf) void {
+ const gpa = elf.arena.child_allocator;
+ {
+ var it = elf.sections.valueIterator();
+ while (it.next()) |sect| {
+ sect.*.data.deinit();
+ sect.*.relocations.deinit(gpa);
+ }
+ }
+ elf.sections.deinit(gpa);
+ elf.local_symbols.deinit(gpa);
+ elf.global_symbols.deinit(gpa);
+ elf.arena.deinit();
+ gpa.destroy(elf);
+}
+
+fn sectionString(sec: Object.Section) []const u8 {
+ return switch (sec) {
+ .undefined => unreachable,
+ .data => "data",
+ .read_only_data => "rodata",
+ .func => "text",
+ .strings => "rodata.str",
+ .custom => |name| name,
+ };
+}
+
+pub fn getSection(elf: *Elf, section_kind: Object.Section) !*std.ArrayList(u8) {
+ const section_name = sectionString(section_kind);
+ const section = elf.sections.get(section_name) orelse blk: {
+ const section = try elf.arena.allocator().create(Section);
+ section.* = .{
+ .data = std.ArrayList(u8).init(elf.arena.child_allocator),
+ .type = std.elf.SHT_PROGBITS,
+ .flags = switch (section_kind) {
+ .func, .custom => std.elf.SHF_ALLOC + std.elf.SHF_EXECINSTR,
+ .strings => std.elf.SHF_ALLOC + std.elf.SHF_MERGE + std.elf.SHF_STRINGS,
+ .read_only_data => std.elf.SHF_ALLOC,
+ .data => std.elf.SHF_ALLOC + std.elf.SHF_WRITE,
+ .undefined => unreachable,
+ },
+ };
+ try elf.sections.putNoClobber(elf.arena.child_allocator, section_name, section);
+ elf.strtab_len += section_name.len + ".\x00".len;
+ break :blk section;
+ };
+ return §ion.data;
+}
+
+pub fn declareSymbol(
+ elf: *Elf,
+ section_kind: Object.Section,
+ maybe_name: ?[]const u8,
+ linkage: std.builtin.GlobalLinkage,
+ @"type": Object.SymbolType,
+ offset: u64,
+ size: u64,
+) ![]const u8 {
+ const section = blk: {
+ if (section_kind == .undefined) break :blk null;
+ const section_name = sectionString(section_kind);
+ break :blk elf.sections.get(section_name);
+ };
+ const binding: u8 = switch (linkage) {
+ .Internal => std.elf.STB_LOCAL,
+ .Strong => std.elf.STB_GLOBAL,
+ .Weak => std.elf.STB_WEAK,
+ .LinkOnce => unreachable,
+ };
+ const sym_type: u8 = switch (@"type") {
+ .func => std.elf.STT_FUNC,
+ .variable => std.elf.STT_OBJECT,
+ .external => std.elf.STT_NOTYPE,
+ };
+ const name = if (maybe_name) |some| some else blk: {
+ defer elf.unnamed_symbol_mangle += 1;
+ break :blk try std.fmt.allocPrint(elf.arena.allocator(), ".L.{d}", .{elf.unnamed_symbol_mangle});
+ };
+
+ const gop = if (linkage == .Internal)
+ try elf.local_symbols.getOrPut(elf.arena.child_allocator, name)
+ else
+ try elf.global_symbols.getOrPut(elf.arena.child_allocator, name);
+
+ if (!gop.found_existing) {
+ gop.value_ptr.* = try elf.arena.allocator().create(Symbol);
+ elf.strtab_len += name.len + 1; // +1 for null byte
+ }
+ gop.value_ptr.*.* = .{
+ .section = section,
+ .size = size,
+ .offset = offset,
+ .info = (binding << 4) + sym_type,
+ };
+ return name;
+}
+
+pub fn addRelocation(elf: *Elf, name: []const u8, section_kind: Object.Section, address: u64, addend: i64) !void {
+ const section_name = sectionString(section_kind);
+ const symbol = elf.local_symbols.get(name) orelse elf.global_symbols.get(name).?; // reference to undeclared symbol
+ const section = elf.sections.get(section_name).?;
+ if (section.relocations.items.len == 0) elf.strtab_len += ".rela".len;
+
+ try section.relocations.append(elf.arena.child_allocator, .{
+ .symbol = symbol,
+ .offset = @intCast(address),
+ .addend = addend,
+ .type = if (symbol.section == null) 4 else 2, // TODO
+ });
+}
+
+/// elf header
+/// sections contents
+/// symbols
+/// relocations
+/// strtab
+/// section headers
+pub fn finish(elf: *Elf, file: std.fs.File) !void {
+ var buf_writer = std.io.bufferedWriter(file.writer());
+ const w = buf_writer.writer();
+
+ var num_sections: std.elf.Elf64_Half = additional_sections;
+ var relocations_len: std.elf.Elf64_Off = 0;
+ var sections_len: std.elf.Elf64_Off = 0;
+ {
+ var it = elf.sections.valueIterator();
+ while (it.next()) |sect| {
+ sections_len += sect.*.data.items.len;
+ relocations_len += sect.*.relocations.items.len * @sizeOf(std.elf.Elf64_Rela);
+ sect.*.index = num_sections;
+ num_sections += 1;
+ num_sections += @intFromBool(sect.*.relocations.items.len != 0);
+ }
+ }
+ const symtab_len = (elf.local_symbols.count() + elf.global_symbols.count() + 1) * @sizeOf(std.elf.Elf64_Sym);
+
+ const symtab_offset = @sizeOf(std.elf.Elf64_Ehdr) + sections_len;
+ const symtab_offset_aligned = std.mem.alignForward(u64, symtab_offset, 8);
+ const rela_offset = symtab_offset_aligned + symtab_len;
+ const strtab_offset = rela_offset + relocations_len;
+ const sh_offset = strtab_offset + elf.strtab_len;
+ const sh_offset_aligned = std.mem.alignForward(u64, sh_offset, 16);
+
+ var elf_header = std.elf.Elf64_Ehdr{
+ .e_ident = .{ 0x7F, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ .e_type = std.elf.ET.REL, // we only produce relocatables
+ .e_machine = elf.obj.comp.target.cpu.arch.toElfMachine(),
+ .e_version = 1,
+ .e_entry = 0, // linker will handle this
+ .e_phoff = 0, // no program header
+ .e_shoff = sh_offset_aligned, // section headers offset
+ .e_flags = 0, // no flags
+ .e_ehsize = @sizeOf(std.elf.Elf64_Ehdr),
+ .e_phentsize = 0, // no program header
+ .e_phnum = 0, // no program header
+ .e_shentsize = @sizeOf(std.elf.Elf64_Shdr),
+ .e_shnum = num_sections,
+ .e_shstrndx = strtab_index,
+ };
+ try w.writeStruct(elf_header);
+
+ // write contents of sections
+ {
+ var it = elf.sections.valueIterator();
+ while (it.next()) |sect| try w.writeAll(sect.*.data.items);
+ }
+
+ // pad to 8 bytes
+ try w.writeByteNTimes(0, @intCast(symtab_offset_aligned - symtab_offset));
+
+ var name_offset: u32 = strtab_default.len;
+ // write symbols
+ {
+ // first symbol must be null
+ try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Sym));
+
+ var sym_index: u16 = 1;
+ var it = elf.local_symbols.iterator();
+ while (it.next()) |entry| {
+ const sym = entry.value_ptr.*;
+ try w.writeStruct(std.elf.Elf64_Sym{
+ .st_name = name_offset,
+ .st_info = sym.info,
+ .st_other = 0,
+ .st_shndx = if (sym.section) |some| some.index else 0,
+ .st_value = sym.offset,
+ .st_size = sym.size,
+ });
+ sym.index = sym_index;
+ sym_index += 1;
+ name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
+ }
+ it = elf.global_symbols.iterator();
+ while (it.next()) |entry| {
+ const sym = entry.value_ptr.*;
+ try w.writeStruct(std.elf.Elf64_Sym{
+ .st_name = name_offset,
+ .st_info = sym.info,
+ .st_other = 0,
+ .st_shndx = if (sym.section) |some| some.index else 0,
+ .st_value = sym.offset,
+ .st_size = sym.size,
+ });
+ sym.index = sym_index;
+ sym_index += 1;
+ name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
+ }
+ }
+
+ // write relocations
+ {
+ var it = elf.sections.valueIterator();
+ while (it.next()) |sect| {
+ for (sect.*.relocations.items) |rela| {
+ try w.writeStruct(std.elf.Elf64_Rela{
+ .r_offset = rela.offset,
+ .r_addend = rela.addend,
+ .r_info = (@as(u64, rela.symbol.index) << 32) | rela.type,
+ });
+ }
+ }
+ }
+
+ // write strtab
+ try w.writeAll(strtab_default);
+ {
+ var it = elf.local_symbols.keyIterator();
+ while (it.next()) |key| try w.print("{s}\x00", .{key.*});
+ it = elf.global_symbols.keyIterator();
+ while (it.next()) |key| try w.print("{s}\x00", .{key.*});
+ }
+ {
+ var it = elf.sections.iterator();
+ while (it.next()) |entry| {
+ if (entry.value_ptr.*.relocations.items.len != 0) try w.writeAll(".rela");
+ try w.print(".{s}\x00", .{entry.key_ptr.*});
+ }
+ }
+
+ // pad to 16 bytes
+ try w.writeByteNTimes(0, @intCast(sh_offset_aligned - sh_offset));
+ // mandatory null header
+ try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Shdr));
+
+ // write strtab section header
+ {
+ var sect_header = std.elf.Elf64_Shdr{
+ .sh_name = strtab_name,
+ .sh_type = std.elf.SHT_STRTAB,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = strtab_offset,
+ .sh_size = elf.strtab_len,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = 1,
+ .sh_entsize = 0,
+ };
+ try w.writeStruct(sect_header);
+ }
+
+ // write symtab section header
+ {
+ var sect_header = std.elf.Elf64_Shdr{
+ .sh_name = symtab_name,
+ .sh_type = std.elf.SHT_SYMTAB,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = symtab_offset_aligned,
+ .sh_size = symtab_len,
+ .sh_link = strtab_index,
+ .sh_info = elf.local_symbols.size + 1,
+ .sh_addralign = 8,
+ .sh_entsize = @sizeOf(std.elf.Elf64_Sym),
+ };
+ try w.writeStruct(sect_header);
+ }
+
+ // remaining section headers
+ {
+ var sect_offset: u64 = @sizeOf(std.elf.Elf64_Ehdr);
+ var rela_sect_offset: u64 = rela_offset;
+ var it = elf.sections.iterator();
+ while (it.next()) |entry| {
+ const sect = entry.value_ptr.*;
+ const rela_count = sect.relocations.items.len;
+ const rela_name_offset: u32 = if (rela_count != 0) @truncate(".rela".len) else 0;
+ try w.writeStruct(std.elf.Elf64_Shdr{
+ .sh_name = rela_name_offset + name_offset,
+ .sh_type = sect.type,
+ .sh_flags = sect.flags,
+ .sh_addr = 0,
+ .sh_offset = sect_offset,
+ .sh_size = sect.data.items.len,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = if (sect.flags & std.elf.SHF_EXECINSTR != 0) 16 else 1,
+ .sh_entsize = 0,
+ });
+
+ if (rela_count != 0) {
+ const size = rela_count * @sizeOf(std.elf.Elf64_Rela);
+ try w.writeStruct(std.elf.Elf64_Shdr{
+ .sh_name = name_offset,
+ .sh_type = std.elf.SHT_RELA,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = rela_sect_offset,
+ .sh_size = rela_count * @sizeOf(std.elf.Elf64_Rela),
+ .sh_link = symtab_index,
+ .sh_info = sect.index,
+ .sh_addralign = 8,
+ .sh_entsize = @sizeOf(std.elf.Elf64_Rela),
+ });
+ rela_sect_offset += size;
+ }
+
+ sect_offset += sect.data.items.len;
+ name_offset += @as(u32, @intCast(entry.key_ptr.len + ".\x00".len)) + rela_name_offset;
+ }
+ }
+ try buf_writer.flush();
+}
deps/aro/pragmas/gcc.zig
@@ -0,0 +1,199 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const TokenIndex = @import("../Tree.zig").TokenIndex;
+
+const GCC = @This();
+
+pragma: Pragma = .{
+ .beforeParse = beforeParse,
+ .beforePreprocess = beforePreprocess,
+ .afterParse = afterParse,
+ .deinit = deinit,
+ .preprocessorHandler = preprocessorHandler,
+ .parserHandler = parserHandler,
+ .preserveTokens = preserveTokens,
+},
+original_options: Diagnostics.Options = .{},
+options_stack: std.ArrayListUnmanaged(Diagnostics.Options) = .{},
+
+const Directive = enum {
+ warning,
+ @"error",
+ diagnostic,
+ poison,
+ const Diagnostics = enum {
+ ignored,
+ warning,
+ @"error",
+ fatal,
+ push,
+ pop,
+ };
+};
+
+fn beforePreprocess(pragma: *Pragma, comp: *Compilation) void {
+ var self = @fieldParentPtr(GCC, "pragma", pragma);
+ self.original_options = comp.diag.options;
+}
+
+fn beforeParse(pragma: *Pragma, comp: *Compilation) void {
+ var self = @fieldParentPtr(GCC, "pragma", pragma);
+ comp.diag.options = self.original_options;
+ self.options_stack.items.len = 0;
+}
+
+fn afterParse(pragma: *Pragma, comp: *Compilation) void {
+ var self = @fieldParentPtr(GCC, "pragma", pragma);
+ comp.diag.options = self.original_options;
+ self.options_stack.items.len = 0;
+}
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+ var gcc = try allocator.create(GCC);
+ gcc.* = .{};
+ return &gcc.pragma;
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+ var self = @fieldParentPtr(GCC, "pragma", pragma);
+ self.options_stack.deinit(comp.gpa);
+ comp.gpa.destroy(self);
+}
+
+fn diagnosticHandler(self: *GCC, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+ const diagnostic_tok = pp.tokens.get(start_idx);
+ if (diagnostic_tok.id == .nl) return;
+
+ const diagnostic = std.meta.stringToEnum(Directive.Diagnostics, pp.expandedSlice(diagnostic_tok)) orelse
+ return error.UnknownPragma;
+
+ switch (diagnostic) {
+ .ignored, .warning, .@"error", .fatal => {
+ const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
+ error.ExpectedStringLiteral => {
+ return pp.comp.diag.add(.{
+ .tag = .pragma_requires_string_literal,
+ .loc = diagnostic_tok.loc,
+ .extra = .{ .str = "GCC diagnostic" },
+ }, diagnostic_tok.expansionSlice());
+ },
+ else => |e| return e,
+ };
+ if (!mem.startsWith(u8, str, "-W")) {
+ const next = pp.tokens.get(start_idx + 1);
+ return pp.comp.diag.add(.{
+ .tag = .malformed_warning_check,
+ .loc = next.loc,
+ .extra = .{ .str = "GCC diagnostic" },
+ }, next.expansionSlice());
+ }
+ const new_kind = switch (diagnostic) {
+ .ignored => Diagnostics.Kind.off,
+ .warning => Diagnostics.Kind.warning,
+ .@"error" => Diagnostics.Kind.@"error",
+ .fatal => Diagnostics.Kind.@"fatal error",
+ else => unreachable,
+ };
+
+ try pp.comp.diag.set(str[2..], new_kind);
+ },
+ .push => try self.options_stack.append(pp.comp.gpa, pp.comp.diag.options),
+ .pop => pp.comp.diag.options = self.options_stack.popOrNull() orelse self.original_options,
+ }
+}
+
+fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+ var self = @fieldParentPtr(GCC, "pragma", pragma);
+ const directive_tok = pp.tokens.get(start_idx + 1);
+ if (directive_tok.id == .nl) return;
+
+ const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse
+ return pp.comp.diag.add(.{
+ .tag = .unknown_gcc_pragma,
+ .loc = directive_tok.loc,
+ }, directive_tok.expansionSlice());
+
+ switch (gcc_pragma) {
+ .warning, .@"error" => {
+ const text = Pragma.pasteTokens(pp, start_idx + 2) catch |err| switch (err) {
+ error.ExpectedStringLiteral => {
+ return pp.comp.diag.add(.{
+ .tag = .pragma_requires_string_literal,
+ .loc = directive_tok.loc,
+ .extra = .{ .str = @tagName(gcc_pragma) },
+ }, directive_tok.expansionSlice());
+ },
+ else => |e| return e,
+ };
+ const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diag.arena.allocator().dupe(u8, text) };
+ const diagnostic_tag: Diagnostics.Tag = if (gcc_pragma == .warning) .pragma_warning_message else .pragma_error_message;
+ return pp.comp.diag.add(
+ .{ .tag = diagnostic_tag, .loc = directive_tok.loc, .extra = extra },
+ directive_tok.expansionSlice(),
+ );
+ },
+ .diagnostic => return self.diagnosticHandler(pp, start_idx + 2) catch |err| switch (err) {
+ error.UnknownPragma => {
+ const tok = pp.tokens.get(start_idx + 2);
+ return pp.comp.diag.add(.{
+ .tag = .unknown_gcc_pragma_directive,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ },
+ else => |e| return e,
+ },
+ .poison => {
+ var i: usize = 2;
+ while (true) : (i += 1) {
+ const tok = pp.tokens.get(start_idx + i);
+ if (tok.id == .nl) break;
+
+ if (!tok.id.isMacroIdentifier()) {
+ return pp.comp.diag.add(.{
+ .tag = .pragma_poison_identifier,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ }
+ const str = pp.expandedSlice(tok);
+ if (pp.defines.get(str) != null) {
+ try pp.comp.diag.add(.{
+ .tag = .pragma_poison_macro,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ }
+ try pp.poisoned_identifiers.put(str, {});
+ }
+ return;
+ },
+ }
+}
+
+fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
+ var self = @fieldParentPtr(GCC, "pragma", pragma);
+ const directive_tok = p.pp.tokens.get(start_idx + 1);
+ if (directive_tok.id == .nl) return;
+ const name = p.pp.expandedSlice(directive_tok);
+ if (mem.eql(u8, name, "diagnostic")) {
+ return self.diagnosticHandler(p.pp, start_idx + 2) catch |err| switch (err) {
+ error.UnknownPragma => {}, // handled during preprocessing
+ error.StopPreprocessing => unreachable, // Only used by #pragma once
+ else => |e| return e,
+ };
+ }
+}
+
+fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
+ const next = pp.tokens.get(start_idx + 1);
+ if (next.id != .nl) {
+ const name = pp.expandedSlice(next);
+ if (mem.eql(u8, name, "poison")) {
+ return false;
+ }
+ }
+ return true;
+}
deps/aro/pragmas/message.zig
@@ -0,0 +1,50 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const TokenIndex = @import("../Tree.zig").TokenIndex;
+const Source = @import("../Source.zig");
+
+const Message = @This();
+
+pragma: Pragma = .{
+ .deinit = deinit,
+ .preprocessorHandler = preprocessorHandler,
+},
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+ var once = try allocator.create(Message);
+ once.* = .{};
+ return &once.pragma;
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+ var self = @fieldParentPtr(Message, "pragma", pragma);
+ comp.gpa.destroy(self);
+}
+
+fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+ const message_tok = pp.tokens.get(start_idx);
+ const message_expansion_locs = message_tok.expansionSlice();
+
+ const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
+ error.ExpectedStringLiteral => {
+ return pp.comp.diag.add(.{
+ .tag = .pragma_requires_string_literal,
+ .loc = message_tok.loc,
+ .extra = .{ .str = "message" },
+ }, message_expansion_locs);
+ },
+ else => |e| return e,
+ };
+
+ const loc = if (message_expansion_locs.len != 0)
+ message_expansion_locs[message_expansion_locs.len - 1]
+ else
+ message_tok.loc;
+ const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diag.arena.allocator().dupe(u8, str) };
+ return pp.comp.diag.add(.{ .tag = .pragma_message, .loc = loc, .extra = extra }, &.{});
+}
deps/aro/pragmas/once.zig
@@ -0,0 +1,56 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const TokenIndex = @import("../Tree.zig").TokenIndex;
+const Source = @import("../Source.zig");
+
+const Once = @This();
+
+pragma: Pragma = .{
+ .afterParse = afterParse,
+ .deinit = deinit,
+ .preprocessorHandler = preprocessorHandler,
+},
+pragma_once: std.AutoHashMap(Source.Id, void),
+preprocess_count: u32 = 0,
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+ var once = try allocator.create(Once);
+ once.* = .{
+ .pragma_once = std.AutoHashMap(Source.Id, void).init(allocator),
+ };
+ return &once.pragma;
+}
+
+fn afterParse(pragma: *Pragma, _: *Compilation) void {
+ var self = @fieldParentPtr(Once, "pragma", pragma);
+ self.pragma_once.clearRetainingCapacity();
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+ var self = @fieldParentPtr(Once, "pragma", pragma);
+ self.pragma_once.deinit();
+ comp.gpa.destroy(self);
+}
+
+fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+ var self = @fieldParentPtr(Once, "pragma", pragma);
+ const name_tok = pp.tokens.get(start_idx);
+ const next = pp.tokens.get(start_idx + 1);
+ if (next.id != .nl) {
+ try pp.comp.diag.add(.{
+ .tag = .extra_tokens_directive_end,
+ .loc = name_tok.loc,
+ }, next.expansionSlice());
+ }
+ const seen = self.preprocess_count == pp.preprocess_count;
+ const prev = try self.pragma_once.fetchPut(name_tok.loc.id, {});
+ if (prev != null and !seen) {
+ return error.StopPreprocessing;
+ }
+ self.preprocess_count = pp.preprocess_count;
+}
deps/aro/pragmas/pack.zig
@@ -0,0 +1,164 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const Tree = @import("../Tree.zig");
+const TokenIndex = Tree.TokenIndex;
+
+const Pack = @This();
+
+pragma: Pragma = .{
+ .deinit = deinit,
+ .parserHandler = parserHandler,
+ .preserveTokens = preserveTokens,
+},
+stack: std.ArrayListUnmanaged(struct { label: []const u8, val: u8 }) = .{},
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+ var pack = try allocator.create(Pack);
+ pack.* = .{};
+ return &pack.pragma;
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+ var self = @fieldParentPtr(Pack, "pragma", pragma);
+ self.stack.deinit(comp.gpa);
+ comp.gpa.destroy(self);
+}
+
+fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
+ var pack = @fieldParentPtr(Pack, "pragma", pragma);
+ var idx = start_idx + 1;
+ const l_paren = p.pp.tokens.get(idx);
+ if (l_paren.id != .l_paren) {
+ return p.pp.comp.diag.add(.{
+ .tag = .pragma_pack_lparen,
+ .loc = l_paren.loc,
+ }, l_paren.expansionSlice());
+ }
+ idx += 1;
+
+ // TODO -fapple-pragma-pack -fxl-pragma-pack
+ const apple_or_xl = false;
+ const tok_ids = p.pp.tokens.items(.id);
+ const arg = idx;
+ switch (tok_ids[arg]) {
+ .identifier => {
+ idx += 1;
+ const Action = enum {
+ show,
+ push,
+ pop,
+ };
+ const action = std.meta.stringToEnum(Action, p.tokSlice(arg)) orelse {
+ return p.errTok(.pragma_pack_unknown_action, arg);
+ };
+ switch (action) {
+ .show => {
+ try p.errExtra(.pragma_pack_show, arg, .{ .unsigned = p.pragma_pack orelse 8 });
+ },
+ .push, .pop => {
+ var new_val: ?u8 = null;
+ var label: ?[]const u8 = null;
+ if (tok_ids[idx] == .comma) {
+ idx += 1;
+ const next = idx;
+ idx += 1;
+ switch (tok_ids[next]) {
+ .pp_num => new_val = (try packInt(p, next)) orelse return,
+ .identifier => {
+ label = p.tokSlice(next);
+ if (tok_ids[idx] == .comma) {
+ idx += 1;
+ const int = idx;
+ idx += 1;
+ if (tok_ids[int] != .pp_num) return p.errTok(.pragma_pack_int_ident, int);
+ new_val = (try packInt(p, int)) orelse return;
+ }
+ },
+ else => return p.errTok(.pragma_pack_int_ident, next),
+ }
+ }
+ if (action == .push) {
+ try pack.stack.append(p.pp.comp.gpa, .{ .label = label orelse "", .val = p.pragma_pack orelse 8 });
+ } else {
+ pack.pop(p, label);
+ if (new_val != null) {
+ try p.errTok(.pragma_pack_undefined_pop, arg);
+ } else if (pack.stack.items.len == 0) {
+ try p.errTok(.pragma_pack_empty_stack, arg);
+ }
+ }
+ if (new_val) |some| {
+ p.pragma_pack = some;
+ }
+ },
+ }
+ },
+ .r_paren => if (apple_or_xl) {
+ pack.pop(p, null);
+ } else {
+ p.pragma_pack = null;
+ },
+ .pp_num => {
+ const new_val = (try packInt(p, arg)) orelse return;
+ idx += 1;
+ if (apple_or_xl) {
+ try pack.stack.append(p.pp.comp.gpa, .{ .label = "", .val = p.pragma_pack });
+ }
+ p.pragma_pack = new_val;
+ },
+ else => {},
+ }
+
+ if (tok_ids[idx] != .r_paren) {
+ return p.errTok(.pragma_pack_rparen, idx);
+ }
+}
+
+fn packInt(p: *Parser, tok_i: TokenIndex) Compilation.Error!?u8 {
+ const res = p.parseNumberToken(tok_i) catch |err| switch (err) {
+ error.ParsingFailed => {
+ try p.errTok(.pragma_pack_int, tok_i);
+ return null;
+ },
+ else => |e| return e,
+ };
+ const int = if (res.val.tag == .int) res.val.getInt(u64) else 99;
+ switch (int) {
+ 1, 2, 4, 8, 16 => return @intCast(int),
+ else => {
+ try p.errTok(.pragma_pack_int, tok_i);
+ return null;
+ },
+ }
+}
+
+fn pop(pack: *Pack, p: *Parser, maybe_label: ?[]const u8) void {
+ if (maybe_label) |label| {
+ var i = pack.stack.items.len;
+ while (i > 0) {
+ i -= 1;
+ if (std.mem.eql(u8, pack.stack.items[i].label, label)) {
+ const prev = pack.stack.orderedRemove(i);
+ p.pragma_pack = prev.val;
+ return;
+ }
+ }
+ } else {
+ const prev = pack.stack.popOrNull() orelse {
+ p.pragma_pack = 2;
+ return;
+ };
+ p.pragma_pack = prev.val;
+ }
+}
+
+fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
+ _ = pp;
+ _ = start_idx;
+ return true;
+}
deps/aro/toolchains/Linux.zig
@@ -0,0 +1,482 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const GCCDetector = @import("../Driver/GCCDetector.zig");
+const Toolchain = @import("../Toolchain.zig");
+const Driver = @import("../Driver.zig");
+const Distro = @import("../Driver/Distro.zig");
+const target_util = @import("../target.zig");
+const system_defaults = @import("system_defaults");
+
+const Linux = @This();
+
+distro: Distro.Tag = .unknown,
+extra_opts: std.ArrayListUnmanaged([]const u8) = .{},
+gcc_detector: GCCDetector = .{},
+
+pub fn discover(self: *Linux, tc: *Toolchain) !void {
+ self.distro = Distro.detect(tc.getTarget(), tc.filesystem);
+ try self.gcc_detector.discover(tc);
+ tc.selected_multilib = self.gcc_detector.selected;
+
+ try self.gcc_detector.appendToolPath(tc);
+ try self.buildExtraOpts(tc);
+ try self.findPaths(tc);
+}
+
+fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void {
+ const gpa = tc.driver.comp.gpa;
+ const target = tc.getTarget();
+ const is_android = target.isAndroid();
+ if (self.distro.isAlpine() or is_android) {
+ try self.extra_opts.ensureUnusedCapacity(gpa, 2);
+ self.extra_opts.appendAssumeCapacity("-z");
+ self.extra_opts.appendAssumeCapacity("now");
+ }
+
+ if (self.distro.isOpenSUSE() or self.distro.isUbuntu() or self.distro.isAlpine() or is_android) {
+ try self.extra_opts.ensureUnusedCapacity(gpa, 2);
+ self.extra_opts.appendAssumeCapacity("-z");
+ self.extra_opts.appendAssumeCapacity("relro");
+ }
+
+ if (target.cpu.arch.isARM() or target.cpu.arch.isAARCH64() or is_android) {
+ try self.extra_opts.ensureUnusedCapacity(gpa, 2);
+ self.extra_opts.appendAssumeCapacity("-z");
+ self.extra_opts.appendAssumeCapacity("max-page-size=4096");
+ }
+
+ if (target.cpu.arch == .arm or target.cpu.arch == .thumb) {
+ try self.extra_opts.append(gpa, "-X");
+ }
+
+ if (!target.cpu.arch.isMIPS() and target.cpu.arch != .hexagon) {
+ const hash_style = if (is_android) .both else self.distro.getHashStyle();
+ try self.extra_opts.append(gpa, switch (hash_style) {
+ inline else => |tag| "--hash-style=" ++ @tagName(tag),
+ });
+ }
+
+ if (system_defaults.enable_linker_build_id) {
+ try self.extra_opts.append(gpa, "--build-id");
+ }
+}
+
+fn addMultiLibPaths(self: *Linux, tc: *Toolchain, sysroot: []const u8, os_lib_dir: []const u8) !void {
+ if (!self.gcc_detector.is_valid) return;
+ const gcc_triple = self.gcc_detector.gcc_triple;
+ const lib_path = self.gcc_detector.parent_lib_path;
+
+ // Add lib/gcc/$triple/$version, with an optional /multilib suffix.
+ try tc.addPathIfExists(&.{ self.gcc_detector.install_path, tc.selected_multilib.gcc_suffix }, .file);
+
+ // Add lib/gcc/$triple/$libdir
+ // For GCC built with --enable-version-specific-runtime-libs.
+ try tc.addPathIfExists(&.{ self.gcc_detector.install_path, "..", os_lib_dir }, .file);
+
+ try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", "..", os_lib_dir, tc.selected_multilib.os_suffix }, .file);
+
+ // If the GCC installation we found is inside of the sysroot, we want to
+ // prefer libraries installed in the parent prefix of the GCC installation.
+ // It is important to *not* use these paths when the GCC installation is
+ // outside of the system root as that can pick up unintended libraries.
+ // This usually happens when there is an external cross compiler on the
+ // host system, and a more minimal sysroot available that is the target of
+ // the cross. Note that GCC does include some of these directories in some
+ // configurations but this seems somewhere between questionable and simply
+ // a bug.
+ if (mem.startsWith(u8, lib_path, sysroot)) {
+ try tc.addPathIfExists(&.{ lib_path, "..", os_lib_dir }, .file);
+ }
+}
+
+fn addMultiArchPaths(self: *Linux, tc: *Toolchain) !void {
+ if (!self.gcc_detector.is_valid) return;
+ const lib_path = self.gcc_detector.parent_lib_path;
+ const gcc_triple = self.gcc_detector.gcc_triple;
+ const multilib = self.gcc_detector.selected;
+ try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", multilib.os_suffix }, .file);
+}
+
+/// TODO: Very incomplete
+fn findPaths(self: *Linux, tc: *Toolchain) !void {
+ const target = tc.getTarget();
+ const sysroot = tc.getSysroot();
+
+ var output: [64]u8 = undefined;
+
+ const os_lib_dir = getOSLibDir(target);
+ const multiarch_triple = getMultiarchTriple(target) orelse target_util.toLLVMTriple(target, &output);
+
+ try self.addMultiLibPaths(tc, sysroot, os_lib_dir);
+
+ try tc.addPathIfExists(&.{ sysroot, "/lib", multiarch_triple }, .file);
+ try tc.addPathIfExists(&.{ sysroot, "/lib", "..", os_lib_dir }, .file);
+
+ if (target.isAndroid()) {
+ // TODO
+ }
+ try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", multiarch_triple }, .file);
+ try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", "..", os_lib_dir }, .file);
+
+ try self.addMultiArchPaths(tc);
+
+ try tc.addPathIfExists(&.{ sysroot, "/lib" }, .file);
+ try tc.addPathIfExists(&.{ sysroot, "/usr", "lib" }, .file);
+}
+
+pub fn deinit(self: *Linux, allocator: std.mem.Allocator) void {
+ self.extra_opts.deinit(allocator);
+}
+
+fn isPIEDefault(self: *const Linux) bool {
+ _ = self;
+ return false;
+}
+
+fn getPIE(self: *const Linux, d: *const Driver) bool {
+ if (d.shared or d.static or d.relocatable or d.static_pie) {
+ return false;
+ }
+ return d.pie orelse self.isPIEDefault();
+}
+
+fn getStaticPIE(self: *const Linux, d: *Driver) !bool {
+ _ = self;
+ if (d.static_pie and d.pie != null) {
+ try d.err("cannot specify 'nopie' along with 'static-pie'");
+ }
+ return d.static_pie;
+}
+
+fn getStatic(self: *const Linux, d: *const Driver) bool {
+ _ = self;
+ return d.static and !d.static_pie;
+}
+
+pub fn getDefaultLinker(self: *const Linux, target: std.Target) []const u8 {
+ _ = self;
+ if (target.isAndroid()) {
+ return "ld.lld";
+ }
+ return "ld";
+}
+
+pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.ArrayList([]const u8)) Compilation.Error!void {
+ const d = tc.driver;
+ const target = tc.getTarget();
+
+ const is_pie = self.getPIE(d);
+ const is_static_pie = try self.getStaticPIE(d);
+ const is_static = self.getStatic(d);
+ const is_android = target.isAndroid();
+ const is_iamcu = target.os.tag == .elfiamcu;
+ const is_ve = target.cpu.arch == .ve;
+ const has_crt_begin_end_files = target.abi != .none; // TODO: clang checks for MIPS vendor
+
+ if (is_pie) {
+ try argv.append("-pie");
+ }
+ if (is_static_pie) {
+ try argv.appendSlice(&.{ "-static", "-pie", "--no-dynamic-linker", "-z", "text" });
+ }
+
+ if (d.rdynamic) {
+ try argv.append("-export-dynamic");
+ }
+
+ if (d.strip) {
+ try argv.append("-s");
+ }
+
+ try argv.appendSlice(self.extra_opts.items);
+ try argv.append("--eh-frame-hdr");
+
+ // Todo: Driver should parse `-EL`/`-EB` for arm to set endianness for arm targets
+ if (target_util.ldEmulationOption(d.comp.target, null)) |emulation| {
+ try argv.appendSlice(&.{ "-m", emulation });
+ } else {
+ try d.err("Unknown target triple");
+ return;
+ }
+ if (d.comp.target.cpu.arch.isRISCV()) {
+ try argv.append("-X");
+ }
+ if (d.shared) {
+ try argv.append("-shared");
+ }
+ if (is_static) {
+ try argv.append("-static");
+ } else {
+ if (d.rdynamic) {
+ try argv.append("-export-dynamic");
+ }
+ if (!d.shared and !is_static_pie and !d.relocatable) {
+ const dynamic_linker = d.comp.target.standardDynamicLinkerPath();
+ // todo: check for --dyld-prefix
+ if (dynamic_linker.get()) |path| {
+ try argv.appendSlice(&.{ "-dynamic-linker", try tc.arena.dupe(u8, path) });
+ } else {
+ try d.err("Could not find dynamic linker path");
+ }
+ }
+ }
+
+ try argv.appendSlice(&.{ "-o", d.output_name orelse "a.out" });
+
+ if (!d.nostdlib and !d.nostartfiles and !d.relocatable) {
+ if (!is_android and !is_iamcu) {
+ if (!d.shared) {
+ const crt1 = if (is_pie)
+ "Scrt1.o"
+ else if (is_static_pie)
+ "rcrt1.o"
+ else
+ "crt1.o";
+ try argv.append(try tc.getFilePath(crt1));
+ }
+ try argv.append(try tc.getFilePath("crti.o"));
+ }
+ if (is_ve) {
+ try argv.appendSlice(&.{ "-z", "max-page-size=0x4000000" });
+ }
+
+ if (is_iamcu) {
+ try argv.append(try tc.getFilePath("crt0.o"));
+ } else if (has_crt_begin_end_files) {
+ var path: []const u8 = "";
+ if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
+ const crt_begin = try tc.getCompilerRt("crtbegin", .object);
+ if (tc.filesystem.exists(crt_begin)) {
+ path = crt_begin;
+ }
+ }
+ if (path.len == 0) {
+ const crt_begin = if (tc.driver.shared)
+ if (is_android) "crtbegin_so.o" else "crtbeginS.o"
+ else if (is_static)
+ if (is_android) "crtbegin_static.o" else "crtbeginT.o"
+ else if (is_pie or is_static_pie)
+ if (is_android) "crtbegin_dynamic.o" else "crtbeginS.o"
+ else if (is_android) "crtbegin_dynamic.o" else "crtbegin.o";
+ path = try tc.getFilePath(crt_begin);
+ }
+ try argv.append(path);
+ }
+ }
+
+ // TODO add -L opts
+ // TODO add -u opts
+
+ try tc.addFilePathLibArgs(argv);
+
+ // TODO handle LTO
+
+ try argv.appendSlice(d.link_objects.items);
+
+ if (!d.nostdlib and !d.relocatable) {
+ if (!d.nodefaultlibs) {
+ if (is_static or is_static_pie) {
+ try argv.append("--start-group");
+ }
+ try tc.addRuntimeLibs(argv);
+
+ // TODO: add pthread if needed
+ if (!d.nolibc) {
+ try argv.append("-lc");
+ }
+ if (is_iamcu) {
+ try argv.append("-lgloss");
+ }
+ if (is_static or is_static_pie) {
+ try argv.append("--end-group");
+ } else {
+ try tc.addRuntimeLibs(argv);
+ }
+ if (is_iamcu) {
+ try argv.appendSlice(&.{ "--as-needed", "-lsoftfp", "--no-as-needed" });
+ }
+ }
+ if (!d.nostartfiles and !is_iamcu) {
+ if (has_crt_begin_end_files) {
+ var path: []const u8 = "";
+ if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
+ const crt_end = try tc.getCompilerRt("crtend", .object);
+ if (tc.filesystem.exists(crt_end)) {
+ path = crt_end;
+ }
+ }
+ if (path.len == 0) {
+ const crt_end = if (d.shared)
+ if (is_android) "crtend_so.o" else "crtendS.o"
+ else if (is_pie or is_static_pie)
+ if (is_android) "crtend_android.o" else "crtendS.o"
+ else if (is_android) "crtend_android.o" else "crtend.o";
+ path = try tc.getFilePath(crt_end);
+ }
+ try argv.append(path);
+ }
+ if (!is_android) {
+ try argv.append(try tc.getFilePath("crtn.o"));
+ }
+ }
+ }
+
+ // TODO add -T args
+}
+
+fn getMultiarchTriple(target: std.Target) ?[]const u8 {
+ const is_android = target.isAndroid();
+ const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6);
+ return switch (target.cpu.arch) {
+ .arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi",
+ .armeb, .thumbeb => if (target.abi == .gnueabihf) "armeb-linux-gnueabihf" else "armeb-linux-gnueabi",
+ .aarch64 => if (is_android) "aarch64-linux-android" else "aarch64-linux-gnu",
+ .aarch64_be => "aarch64_be-linux-gnu",
+ .x86 => if (is_android) "i686-linux-android" else "i386-linux-gnu",
+ .x86_64 => if (is_android) "x86_64-linux-android" else if (target.abi == .gnux32) "x86_64-linux-gnux32" else "x86_64-linux-gnu",
+ .m68k => "m68k-linux-gnu",
+ .mips => if (is_mips_r6) "mipsisa32r6-linux-gnu" else "mips-linux-gnu",
+ .mipsel => if (is_android) "mipsel-linux-android" else if (is_mips_r6) "mipsisa32r6el-linux-gnu" else "mipsel-linux-gnu",
+ .powerpcle => "powerpcle-linux-gnu",
+ .powerpc64 => "powerpc64-linux-gnu",
+ .powerpc64le => "powerpc64le-linux-gnu",
+ .riscv64 => "riscv64-linux-gnu",
+ .sparc => "sparc-linux-gnu",
+ .sparc64 => "sparc64-linux-gnu",
+ .s390x => "s390x-linux-gnu",
+
+ // TODO: expand this
+ else => null,
+ };
+}
+
+fn getOSLibDir(target: std.Target) []const u8 {
+ switch (target.cpu.arch) {
+ .x86,
+ .powerpc,
+ .powerpcle,
+ .sparc,
+ .sparcel,
+ => return "lib32",
+ else => {},
+ }
+ if (target.cpu.arch == .x86_64 and (target.abi == .gnux32 or target.abi == .muslx32)) {
+ return "libx32";
+ }
+ if (target.cpu.arch == .riscv32) {
+ return "lib32";
+ }
+ if (target.ptrBitWidth() == 32) {
+ return "lib";
+ }
+ return "lib64";
+}
+
+test Linux {
+ if (@import("builtin").os.tag == .windows) return error.SkipZigTest;
+
+ var arena_instance = std.heap.ArenaAllocator.init(std.testing.allocator);
+ defer arena_instance.deinit();
+ const arena = arena_instance.allocator();
+
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+ comp.environment = .{
+ .path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+ };
+
+ const raw_triple = "x86_64-linux-gnu";
+ const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = raw_triple }) catch unreachable;
+ comp.target = cross.toTarget(); // TODO deprecated
+ comp.langopts.setEmulatedCompiler(.gcc);
+
+ var driver: Driver = .{ .comp = &comp };
+ defer driver.deinit();
+ driver.raw_target_triple = raw_triple;
+
+ const link_obj = try driver.comp.gpa.dupe(u8, "/tmp/foo.o");
+ try driver.link_objects.append(driver.comp.gpa, link_obj);
+ driver.temp_file_count += 1;
+
+ var toolchain: Toolchain = .{ .driver = &driver, .arena = arena, .filesystem = .{ .fake = &.{
+ .{ .path = "/tmp" },
+ .{ .path = "/usr" },
+ .{ .path = "/usr/lib64" },
+ .{ .path = "/usr/bin" },
+ .{ .path = "/usr/bin/ld", .executable = true },
+ .{ .path = "/lib" },
+ .{ .path = "/lib/x86_64-linux-gnu" },
+ .{ .path = "/lib/x86_64-linux-gnu/crt1.o" },
+ .{ .path = "/lib/x86_64-linux-gnu/crti.o" },
+ .{ .path = "/lib/x86_64-linux-gnu/crtn.o" },
+ .{ .path = "/lib64" },
+ .{ .path = "/usr/lib" },
+ .{ .path = "/usr/lib/gcc" },
+ .{ .path = "/usr/lib/gcc/x86_64-linux-gnu" },
+ .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9" },
+ .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o" },
+ .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o" },
+ .{ .path = "/usr/lib/x86_64-linux-gnu" },
+ .{ .path = "/etc/lsb-release", .contents =
+ \\DISTRIB_ID=Ubuntu
+ \\DISTRIB_RELEASE=20.04
+ \\DISTRIB_CODENAME=focal
+ \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
+ \\
+ },
+ } } };
+ defer toolchain.deinit();
+
+ try toolchain.discover();
+
+ var argv = std.ArrayList([]const u8).init(driver.comp.gpa);
+ defer argv.deinit();
+
+ var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ const linker_path = try toolchain.getLinkerPath(&linker_path_buf);
+ try argv.append(linker_path);
+
+ try toolchain.buildLinkerArgs(&argv);
+
+ const expected = [_][]const u8{
+ "/usr/bin/ld",
+ "-z",
+ "relro",
+ "--hash-style=gnu",
+ "--eh-frame-hdr",
+ "-m",
+ "elf_x86_64",
+ "-dynamic-linker",
+ "/lib64/ld-linux-x86-64.so.2",
+ "-o",
+ "a.out",
+ "/lib/x86_64-linux-gnu/crt1.o",
+ "/lib/x86_64-linux-gnu/crti.o",
+ "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o",
+ "-L/usr/lib/gcc/x86_64-linux-gnu/9",
+ "-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64",
+ "-L/lib/x86_64-linux-gnu",
+ "-L/lib/../lib64",
+ "-L/usr/lib/x86_64-linux-gnu",
+ "-L/usr/lib/../lib64",
+ "-L/lib",
+ "-L/usr/lib",
+ link_obj,
+ "-lgcc",
+ "--as-needed",
+ "-lgcc_s",
+ "--no-as-needed",
+ "-lc",
+ "-lgcc",
+ "--as-needed",
+ "-lgcc_s",
+ "--no-as-needed",
+ "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o",
+ "/lib/x86_64-linux-gnu/crtn.o",
+ };
+ try std.testing.expectEqual(expected.len, argv.items.len);
+ for (expected, argv.items) |expected_item, actual_item| {
+ try std.testing.expectEqualStrings(expected_item, actual_item);
+ }
+}
deps/aro/Attribute.zig
@@ -0,0 +1,1346 @@
+const std = @import("std");
+const mem = std.mem;
+const ZigType = std.builtin.Type;
+const CallingConvention = @import("lib.zig").CallingConvention;
+const Compilation = @import("Compilation.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const Parser = @import("Parser.zig");
+const Tree = @import("Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const TokenIndex = Tree.TokenIndex;
+const Type = @import("Type.zig");
+const Value = @import("Value.zig");
+
+const Attribute = @This();
+
+tag: Tag,
+syntax: Syntax,
+args: Arguments,
+
+pub const Syntax = enum {
+ c2x,
+ declspec,
+ gnu,
+ keyword,
+};
+
+pub const Kind = enum {
+ c2x,
+ declspec,
+ gnu,
+
+ pub fn toSyntax(kind: Kind) Syntax {
+ return switch (kind) {
+ .c2x => .c2x,
+ .declspec => .declspec,
+ .gnu => .gnu,
+ };
+ }
+};
+
+pub const ArgumentType = enum {
+ string,
+ identifier,
+ int,
+ alignment,
+ float,
+ expression,
+ nullptr_t,
+
+ pub fn toString(self: ArgumentType) []const u8 {
+ return switch (self) {
+ .string => "a string",
+ .identifier => "an identifier",
+ .int, .alignment => "an integer constant",
+ .nullptr_t => "nullptr",
+ .float => "a floating point number",
+ .expression => "an expression",
+ };
+ }
+
+ fn fromType(comptime T: type) ArgumentType {
+ return switch (T) {
+ []const u8 => .string,
+ Identifier => .identifier,
+ u32 => .int,
+ Alignment => .alignment,
+ CallingConvention => .identifier,
+ else => switch (@typeInfo(T)) {
+ .Enum => if (T.opts.enum_kind == .string) .string else .identifier,
+ else => unreachable,
+ },
+ };
+ }
+
+ fn fromVal(value: Value) ArgumentType {
+ return switch (value.tag) {
+ .int => .int,
+ .bytes => .string,
+ .unavailable => .expression,
+ .float => .float,
+ .nullptr_t => .nullptr_t,
+ };
+ }
+};
+
+fn getArguments(comptime descriptor: type) []const ZigType.StructField {
+ return if (@hasDecl(descriptor, "Args")) std.meta.fields(descriptor.Args) else &.{};
+}
+
+/// number of required arguments
+pub fn requiredArgCount(attr: Tag) u32 {
+ switch (attr) {
+ inline else => |tag| {
+ comptime var needed = 0;
+ comptime {
+ const fields = getArguments(@field(attributes, @tagName(tag)));
+ for (fields) |arg_field| {
+ if (!mem.eql(u8, arg_field.name, "__name_tok") and @typeInfo(arg_field.type) != .Optional) needed += 1;
+ }
+ }
+ return needed;
+ },
+ }
+}
+
+/// maximum number of args that can be passed
+pub fn maxArgCount(attr: Tag) u32 {
+ switch (attr) {
+ inline else => |tag| {
+ comptime var max = 0;
+ comptime {
+ const fields = getArguments(@field(attributes, @tagName(tag)));
+ for (fields) |arg_field| {
+ if (!mem.eql(u8, arg_field.name, "__name_tok")) max += 1;
+ }
+ }
+ return max;
+ },
+ }
+}
+
+fn UnwrapOptional(comptime T: type) type {
+ return switch (@typeInfo(T)) {
+ .Optional => |optional| optional.child,
+ else => T,
+ };
+}
+
+pub const Formatting = struct {
+ /// The quote char (single or double) to use when printing identifiers/strings corresponding
+ /// to the enum in the first field of the Args of `attr`. Identifier enums use single quotes, string enums
+ /// use double quotes
+ fn quoteChar(attr: Tag) []const u8 {
+ switch (attr) {
+ .calling_convention => unreachable,
+ inline else => |tag| {
+ const fields = getArguments(@field(attributes, @tagName(tag)));
+
+ if (fields.len == 0) unreachable;
+ const Unwrapped = UnwrapOptional(fields[0].type);
+ if (@typeInfo(Unwrapped) != .Enum) unreachable;
+
+ return if (Unwrapped.opts.enum_kind == .identifier) "'" else "\"";
+ },
+ }
+ }
+
+ /// returns a comma-separated string of quoted enum values, representing the valid
+ /// choices for the string or identifier enum of the first field of the Args of `attr`.
+ pub fn choices(attr: Tag) []const u8 {
+ switch (attr) {
+ .calling_convention => unreachable,
+ inline else => |tag| {
+ const fields = getArguments(@field(attributes, @tagName(tag)));
+
+ if (fields.len == 0) unreachable;
+ const Unwrapped = UnwrapOptional(fields[0].type);
+ if (@typeInfo(Unwrapped) != .Enum) unreachable;
+
+ const enum_fields = @typeInfo(Unwrapped).Enum.fields;
+ @setEvalBranchQuota(3000);
+ const quote = comptime quoteChar(@enumFromInt(@intFromEnum(tag)));
+ comptime var values: []const u8 = quote ++ enum_fields[0].name ++ quote;
+ inline for (enum_fields[1..]) |enum_field| {
+ values = values ++ ", ";
+ values = values ++ quote ++ enum_field.name ++ quote;
+ }
+ return values;
+ },
+ }
+ }
+};
+
+/// Checks if the first argument (if it exists) is an identifier enum
+pub fn wantsIdentEnum(attr: Tag) bool {
+ switch (attr) {
+ .calling_convention => return false,
+ inline else => |tag| {
+ const fields = getArguments(@field(attributes, @tagName(tag)));
+
+ if (fields.len == 0) return false;
+ const Unwrapped = UnwrapOptional(fields[0].type);
+ if (@typeInfo(Unwrapped) != .Enum) return false;
+
+ return Unwrapped.opts.enum_kind == .identifier;
+ },
+ }
+}
+
+pub fn diagnoseIdent(attr: Tag, arguments: *Arguments, ident: []const u8) ?Diagnostics.Message {
+ switch (attr) {
+ inline else => |tag| {
+ const fields = getArguments(@field(attributes, @tagName(tag)));
+ if (fields.len == 0) unreachable;
+ const Unwrapped = UnwrapOptional(fields[0].type);
+ if (@typeInfo(Unwrapped) != .Enum) unreachable;
+ if (std.meta.stringToEnum(Unwrapped, normalize(ident))) |enum_val| {
+ @field(@field(arguments, @tagName(tag)), fields[0].name) = enum_val;
+ return null;
+ }
+ return Diagnostics.Message{
+ .tag = .unknown_attr_enum,
+ .extra = .{ .attr_enum = .{ .tag = attr } },
+ };
+ },
+ }
+}
+
+pub fn wantsAlignment(attr: Tag, idx: usize) bool {
+ switch (attr) {
+ inline else => |tag| {
+ const fields = getArguments(@field(attributes, @tagName(tag)));
+ if (fields.len == 0) return false;
+
+ return switch (idx) {
+ inline 0...fields.len - 1 => |i| UnwrapOptional(fields[i].type) == Alignment,
+ else => false,
+ };
+ },
+ }
+}
+
+pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, val: Value, ty: Type, comp: *Compilation) ?Diagnostics.Message {
+ switch (attr) {
+ inline else => |tag| {
+ const arg_fields = getArguments(@field(attributes, @tagName(tag)));
+ if (arg_fields.len == 0) unreachable;
+
+ switch (arg_idx) {
+ inline 0...arg_fields.len - 1 => |arg_i| {
+ if (UnwrapOptional(arg_fields[arg_i].type) != Alignment) unreachable;
+
+ if (val.tag != .int) return Diagnostics.Message{ .tag = .alignas_unavailable };
+ if (val.compare(.lt, Value.int(0), ty, comp)) {
+ return Diagnostics.Message{ .tag = .negative_alignment, .extra = .{ .signed = val.signExtend(ty, comp) } };
+ }
+ const requested = std.math.cast(u29, val.data.int) orelse {
+ return Diagnostics.Message{ .tag = .maximum_alignment, .extra = .{ .unsigned = val.data.int } };
+ };
+ if (!std.mem.isValidAlign(requested)) return Diagnostics.Message{ .tag = .non_pow2_align };
+
+ @field(@field(arguments, @tagName(tag)), arg_fields[arg_i].name) = Alignment{ .requested = requested };
+ return null;
+ },
+ else => unreachable,
+ }
+ },
+ }
+}
+
+fn diagnoseField(
+ comptime decl: ZigType.Declaration,
+ comptime field: ZigType.StructField,
+ comptime wanted: type,
+ arguments: *Arguments,
+ val: Value,
+ node: Tree.Node,
+ strings: []const u8,
+) ?Diagnostics.Message {
+ switch (val.tag) {
+ .int => {
+ if (@typeInfo(wanted) == .Int) {
+ @field(@field(arguments, decl.name), field.name) = val.getInt(wanted);
+ return null;
+ }
+ },
+ .bytes => {
+ const bytes = val.data.bytes.trim(1); // remove null terminator
+ if (wanted == Value.ByteRange) {
+ @field(@field(arguments, decl.name), field.name) = bytes;
+ return null;
+ } else if (@typeInfo(wanted) == .Enum and @hasDecl(wanted, "opts") and wanted.opts.enum_kind == .string) {
+ const str = bytes.slice(strings);
+ if (std.meta.stringToEnum(wanted, str)) |enum_val| {
+ @field(@field(arguments, decl.name), field.name) = enum_val;
+ return null;
+ } else {
+ @setEvalBranchQuota(3000);
+ return Diagnostics.Message{
+ .tag = .unknown_attr_enum,
+ .extra = .{ .attr_enum = .{ .tag = std.meta.stringToEnum(Tag, decl.name).? } },
+ };
+ }
+ }
+ },
+ else => {
+ if (wanted == Identifier and node.tag == .decl_ref_expr) {
+ @field(@field(arguments, decl.name), field.name) = Identifier{ .tok = node.data.decl_ref };
+ return null;
+ }
+ },
+ }
+ return Diagnostics.Message{
+ .tag = .attribute_arg_invalid,
+ .extra = .{ .attr_arg_type = .{ .expected = ArgumentType.fromType(wanted), .actual = ArgumentType.fromVal(val) } },
+ };
+}
+
+pub fn diagnose(attr: Tag, arguments: *Arguments, arg_idx: u32, val: Value, node: Tree.Node, strings: []const u8) ?Diagnostics.Message {
+ switch (attr) {
+ inline else => |tag| {
+ const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
+ const max_arg_count = comptime maxArgCount(tag);
+ if (arg_idx >= max_arg_count) return Diagnostics.Message{
+ .tag = .attribute_too_many_args,
+ .extra = .{ .attr_arg_count = .{ .attribute = attr, .expected = max_arg_count } },
+ };
+ const arg_fields = getArguments(@field(attributes, decl.name));
+ switch (arg_idx) {
+ inline 0...arg_fields.len - 1 => |arg_i| {
+ return diagnoseField(decl, arg_fields[arg_i], UnwrapOptional(arg_fields[arg_i].type), arguments, val, node, strings);
+ },
+ else => unreachable,
+ }
+ },
+ }
+}
+
+const EnumTypes = enum {
+ string,
+ identifier,
+};
+pub const Alignment = struct {
+ node: NodeIndex = .none,
+ requested: u29,
+};
+pub const Identifier = struct {
+ tok: TokenIndex = 0,
+};
+
+const attributes = struct {
+ pub const access = struct {
+ const gnu = "access";
+
+ const Args = struct {
+ access_mode: enum {
+ read_only,
+ read_write,
+ write_only,
+ none,
+
+ const opts = struct {
+ const enum_kind = .identifier;
+ };
+ },
+ ref_index: u32,
+ size_index: ?u32 = null,
+ };
+ };
+ pub const alias = struct {
+ const gnu = "alias";
+ const Args = struct {
+ alias: Value.ByteRange,
+ };
+ };
+ pub const aligned = struct {
+ const gnu = "aligned";
+ const declspec = "align";
+
+ const Args = struct {
+ alignment: ?Alignment = null,
+ __name_tok: TokenIndex,
+ };
+ };
+ pub const alloc_align = struct {
+ const gnu = "alloc_align";
+
+ const Args = struct {
+ position: u32,
+ };
+ };
+ pub const alloc_size = struct {
+ const gnu = "alloc_size";
+
+ const Args = struct {
+ position_1: u32,
+ position_2: ?u32 = null,
+ };
+ };
+ pub const allocate = struct {
+ const declspec = "allocate";
+
+ const Args = struct {
+ segname: Value.ByteRange,
+ };
+ };
+ pub const allocator = struct {
+ const declspec = "allocator";
+ };
+ pub const always_inline = struct {
+ const gnu = "always_inline";
+ };
+ pub const appdomain = struct {
+ const declspec = "appdomain";
+ };
+ pub const artificial = struct {
+ const gnu = "artificial";
+ };
+ pub const assume_aligned = struct {
+ const gnu = "assume_aligned";
+ const Args = struct {
+ alignment: Alignment,
+ offset: ?u32 = null,
+ };
+ };
+ pub const cleanup = struct {
+ const gnu = "cleanup";
+ const Args = struct {
+ function: Identifier,
+ };
+ };
+ pub const code_seg = struct {
+ const declspec = "code_seg";
+ const Args = struct {
+ segname: Value.ByteRange,
+ };
+ };
+ pub const cold = struct {
+ const gnu = "cold";
+ };
+ pub const common = struct {
+ const gnu = "common";
+ };
+ pub const @"const" = struct {
+ const gnu = "const";
+ };
+ pub const constructor = struct {
+ const gnu = "constructor";
+ const Args = struct {
+ priority: ?u32 = null,
+ };
+ };
+ pub const copy = struct {
+ const gnu = "copy";
+ const Args = struct {
+ function: Identifier,
+ };
+ };
+ pub const deprecated = struct {
+ const gnu = "deprecated";
+ const declspec = "deprecated";
+ const c2x = "deprecated";
+
+ const Args = struct {
+ msg: ?Value.ByteRange = null,
+ __name_tok: TokenIndex,
+ };
+ };
+ pub const designated_init = struct {
+ const gnu = "designated_init";
+ };
+ pub const destructor = struct {
+ const gnu = "destructor";
+ const Args = struct {
+ priority: ?u32 = null,
+ };
+ };
+ pub const dllexport = struct {
+ const declspec = "dllexport";
+ };
+ pub const dllimport = struct {
+ const declspec = "dllimport";
+ };
+ pub const @"error" = struct {
+ const gnu = "error";
+ const Args = struct {
+ msg: Value.ByteRange,
+ __name_tok: TokenIndex,
+ };
+ };
+ pub const externally_visible = struct {
+ const gnu = "externally_visible";
+ };
+ pub const fallthrough = struct {
+ const gnu = "fallthrough";
+ const c2x = "fallthrough";
+ };
+ pub const flatten = struct {
+ const gnu = "flatten";
+ };
+ pub const format = struct {
+ const gnu = "format";
+ const Args = struct {
+ archetype: enum {
+ printf,
+ scanf,
+ strftime,
+ strfmon,
+
+ const opts = struct {
+ const enum_kind = .identifier;
+ };
+ },
+ string_index: u32,
+ first_to_check: u32,
+ };
+ };
+ pub const format_arg = struct {
+ const gnu = "format_arg";
+ const Args = struct {
+ string_index: u32,
+ };
+ };
+ pub const gnu_inline = struct {
+ const gnu = "gnu_inline";
+ };
+ pub const hot = struct {
+ const gnu = "hot";
+ };
+ pub const ifunc = struct {
+ const gnu = "ifunc";
+ const Args = struct {
+ resolver: Value.ByteRange,
+ };
+ };
+ pub const interrupt = struct {
+ const gnu = "interrupt";
+ };
+ pub const interrupt_handler = struct {
+ const gnu = "interrupt_handler";
+ };
+ pub const jitintrinsic = struct {
+ const declspec = "jitintrinsic";
+ };
+ pub const leaf = struct {
+ const gnu = "leaf";
+ };
+ pub const malloc = struct {
+ const gnu = "malloc";
+ };
+ pub const may_alias = struct {
+ const gnu = "may_alias";
+ };
+ pub const mode = struct {
+ const gnu = "mode";
+ const Args = struct {
+ mode: enum {
+ // zig fmt: off
+ byte, word, pointer,
+ BI, QI, HI,
+ PSI, SI, PDI,
+ DI, TI, OI,
+ XI, QF, HF,
+ TQF, SF, DF,
+ XF, SD, DD,
+ TD, TF, QQ,
+ HQ, SQ, DQ,
+ TQ, UQQ, UHQ,
+ USQ, UDQ, UTQ,
+ HA, SA, DA,
+ TA, UHA, USA,
+ UDA, UTA, CC,
+ BLK, VOID, QC,
+ HC, SC, DC,
+ XC, TC, CQI,
+ CHI, CSI, CDI,
+ CTI, COI, CPSI,
+ BND32, BND64,
+ // zig fmt: on
+
+ const opts = struct {
+ const enum_kind = .identifier;
+ };
+ },
+ };
+ };
+ pub const naked = struct {
+ const declspec = "naked";
+ };
+ pub const no_address_safety_analysis = struct {
+ const gnu = "no_address_safety_analysise";
+ };
+ pub const no_icf = struct {
+ const gnu = "no_icf";
+ };
+ pub const no_instrument_function = struct {
+ const gnu = "no_instrument_function";
+ };
+ pub const no_profile_instrument_function = struct {
+ const gnu = "no_profile_instrument_function";
+ };
+ pub const no_reorder = struct {
+ const gnu = "no_reorder";
+ };
+ pub const no_sanitize = struct {
+ const gnu = "no_sanitize";
+ /// Todo: represent args as union?
+ const Args = struct {
+ alignment: Value.ByteRange,
+ object_size: ?Value.ByteRange = null,
+ };
+ };
+ pub const no_sanitize_address = struct {
+ const gnu = "no_sanitize_address";
+ const declspec = "no_sanitize_address";
+ };
+ pub const no_sanitize_coverage = struct {
+ const gnu = "no_sanitize_coverage";
+ };
+ pub const no_sanitize_thread = struct {
+ const gnu = "no_sanitize_thread";
+ };
+ pub const no_sanitize_undefined = struct {
+ const gnu = "no_sanitize_undefined";
+ };
+ pub const no_split_stack = struct {
+ const gnu = "no_split_stack";
+ };
+ pub const no_stack_limit = struct {
+ const gnu = "no_stack_limit";
+ };
+ pub const no_stack_protector = struct {
+ const gnu = "no_stack_protector";
+ };
+ pub const @"noalias" = struct {
+ const declspec = "noalias";
+ };
+ pub const noclone = struct {
+ const gnu = "noclone";
+ };
+ pub const nocommon = struct {
+ const gnu = "nocommon";
+ };
+ pub const nodiscard = struct {
+ const c2x = "nodiscard";
+ };
+ pub const noinit = struct {
+ const gnu = "noinit";
+ };
+ pub const @"noinline" = struct {
+ const gnu = "noinline";
+ const declspec = "noinline";
+ };
+ pub const noipa = struct {
+ const gnu = "noipa";
+ };
+ // TODO: arbitrary number of arguments
+ // const nonnull = struct {
+ // const gnu = "nonnull";
+ // const Args = struct {
+ // arg_index: []const u32,
+ // };
+ // };
+ pub const nonstring = struct {
+ const gnu = "nonstring";
+ };
+ pub const noplt = struct {
+ const gnu = "noplt";
+ };
+ pub const @"noreturn" = struct {
+ const gnu = "noreturn";
+ const c2x = "noreturn";
+ const declspec = "noreturn";
+ };
+ // TODO: union args ?
+ // const optimize = struct {
+ // const gnu = "optimize";
+ // const Args = struct {
+ // optimize, // u32 | []const u8 -- optimize?
+ // };
+ // };
+ pub const @"packed" = struct {
+ const gnu = "packed";
+ };
+ pub const patchable_function_entry = struct {
+ const gnu = "patchable_function_entry";
+ };
+ pub const persistent = struct {
+ const gnu = "persistent";
+ };
+ pub const process = struct {
+ const declspec = "process";
+ };
+ pub const pure = struct {
+ const gnu = "pure";
+ };
+ pub const reproducible = struct {
+ const c2x = "reproducible";
+ };
+ pub const restrict = struct {
+ const declspec = "restrict";
+ };
+ pub const retain = struct {
+ const gnu = "retain";
+ };
+ pub const returns_nonnull = struct {
+ const gnu = "returns_nonnull";
+ };
+ pub const returns_twice = struct {
+ const gnu = "returns_twice";
+ };
+ pub const safebuffers = struct {
+ const declspec = "safebuffers";
+ };
+ pub const scalar_storage_order = struct {
+ const gnu = "scalar_storage_order";
+ const Args = struct {
+ order: enum {
+ @"little-endian",
+ @"big-endian",
+
+ const opts = struct {
+ const enum_kind = .string;
+ };
+ },
+ };
+ };
+ pub const section = struct {
+ const gnu = "section";
+ const Args = struct {
+ name: Value.ByteRange,
+ };
+ };
+ pub const selectany = struct {
+ const declspec = "selectany";
+ };
+ pub const sentinel = struct {
+ const gnu = "sentinel";
+ const Args = struct {
+ position: ?u32 = null,
+ };
+ };
+ pub const simd = struct {
+ const gnu = "simd";
+ const Args = struct {
+ mask: ?enum {
+ notinbranch,
+ inbranch,
+
+ const opts = struct {
+ const enum_kind = .string;
+ };
+ } = null,
+ };
+ };
+ pub const spectre = struct {
+ const declspec = "spectre";
+ const Args = struct {
+ arg: enum {
+ nomitigation,
+
+ const opts = struct {
+ const enum_kind = .identifier;
+ };
+ },
+ };
+ };
+ pub const stack_protect = struct {
+ const gnu = "stack_protect";
+ };
+ pub const symver = struct {
+ const gnu = "symver";
+ const Args = struct {
+ version: Value.ByteRange, // TODO: validate format "name2@nodename"
+ };
+ };
+ pub const target = struct {
+ const gnu = "target";
+ const Args = struct {
+ options: Value.ByteRange, // TODO: multiple arguments
+ };
+ };
+ pub const target_clones = struct {
+ const gnu = "target_clones";
+ const Args = struct {
+ options: Value.ByteRange, // TODO: multiple arguments
+ };
+ };
+ pub const thread = struct {
+ const declspec = "thread";
+ };
+ pub const tls_model = struct {
+ const gnu = "tls_model";
+ const Args = struct {
+ model: enum {
+ @"global-dynamic",
+ @"local-dynamic",
+ @"initial-exec",
+ @"local-exec",
+
+ const opts = struct {
+ const enum_kind = .string;
+ };
+ },
+ };
+ };
+ pub const transparent_union = struct {
+ const gnu = "transparent_union";
+ };
+ pub const unavailable = struct {
+ const gnu = "unavailable";
+ const Args = struct {
+ msg: ?Value.ByteRange = null,
+ __name_tok: TokenIndex,
+ };
+ };
+ pub const uninitialized = struct {
+ const gnu = "uninitialized";
+ };
+ pub const unsequenced = struct {
+ const c2x = "unsequenced";
+ };
+ pub const unused = struct {
+ const gnu = "unused";
+ const c2x = "maybe_unused";
+ };
+ pub const used = struct {
+ const gnu = "used";
+ };
+ pub const uuid = struct {
+ const declspec = "uuid";
+ const Args = struct {
+ uuid: Value.ByteRange,
+ };
+ };
+ pub const vector_size = struct {
+ const gnu = "vector_size";
+ const Args = struct {
+ bytes: u32, // TODO: validate "The bytes argument must be a positive power-of-two multiple of the base type size"
+ };
+ };
+ pub const visibility = struct {
+ const gnu = "visibility";
+ const Args = struct {
+ visibility_type: enum {
+ default,
+ hidden,
+ internal,
+ protected,
+
+ const opts = struct {
+ const enum_kind = .string;
+ };
+ },
+ };
+ };
+ pub const warn_if_not_aligned = struct {
+ const gnu = "warn_if_not_aligned";
+ const Args = struct {
+ alignment: Alignment,
+ };
+ };
+ pub const warn_unused_result = struct {
+ const gnu = "warn_unused_result";
+ };
+ pub const warning = struct {
+ const gnu = "warning";
+ const Args = struct {
+ msg: Value.ByteRange,
+ __name_tok: TokenIndex,
+ };
+ };
+ pub const weak = struct {
+ const gnu = "weak";
+ };
+ pub const weakref = struct {
+ const gnu = "weakref";
+ const Args = struct {
+ target: ?Value.ByteRange = null,
+ };
+ };
+ pub const zero_call_used_regs = struct {
+ const gnu = "zero_call_used_regs";
+ const Args = struct {
+ choice: enum {
+ skip,
+ used,
+ @"used-gpr",
+ @"used-arg",
+ @"used-gpr-arg",
+ all,
+ @"all-gpr",
+ @"all-arg",
+ @"all-gpr-arg",
+
+ const opts = struct {
+ const enum_kind = .string;
+ };
+ },
+ };
+ };
+ pub const asm_label = struct {
+ const Args = struct {
+ name: Value.ByteRange,
+ };
+ };
+ pub const calling_convention = struct {
+ const Args = struct {
+ cc: CallingConvention,
+ };
+ };
+};
+
+pub const Tag = std.meta.DeclEnum(attributes);
+
+pub const Arguments = blk: {
+ const decls = @typeInfo(attributes).Struct.decls;
+ var union_fields: [decls.len]ZigType.UnionField = undefined;
+ inline for (decls, &union_fields) |decl, *field| {
+ field.* = .{
+ .name = decl.name,
+ .type = if (@hasDecl(@field(attributes, decl.name), "Args")) @field(attributes, decl.name).Args else void,
+ .alignment = 0,
+ };
+ }
+
+ break :blk @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = null,
+ .fields = &union_fields,
+ .decls = &.{},
+ },
+ });
+};
+
+pub fn ArgumentsForTag(comptime tag: Tag) type {
+ const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
+ return if (@hasDecl(@field(attributes, decl.name), "Args")) @field(attributes, decl.name).Args else void;
+}
+
+pub fn initArguments(tag: Tag, name_tok: TokenIndex) Arguments {
+ switch (tag) {
+ inline else => |arg_tag| {
+ const union_element = @field(attributes, @tagName(arg_tag));
+ const has_args = @hasDecl(union_element, "Args");
+ const init = if (has_args) std.mem.zeroInit(union_element.Args, .{}) else {};
+ var args = @unionInit(Arguments, @tagName(arg_tag), init);
+ if (has_args and @hasField(@field(attributes, @tagName(arg_tag)).Args, "__name_tok")) {
+ @field(args, @tagName(arg_tag)).__name_tok = name_tok;
+ }
+ return args;
+ },
+ }
+}
+
+pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag {
+ return switch (kind) {
+ .c2x => fromStringC2X(namespace, name),
+ .declspec => fromStringDeclspec(name),
+ .gnu => fromStringGnu(name),
+ };
+}
+
+fn fromStringGnu(name: []const u8) ?Tag {
+ const normalized = normalize(name);
+ const decls = @typeInfo(attributes).Struct.decls;
+ @setEvalBranchQuota(3000);
+ inline for (decls, 0..) |decl, i| {
+ if (@hasDecl(@field(attributes, decl.name), "gnu")) {
+ if (mem.eql(u8, @field(attributes, decl.name).gnu, normalized)) {
+ return @enumFromInt(i);
+ }
+ }
+ }
+ return null;
+}
+
+fn fromStringC2X(namespace: ?[]const u8, name: []const u8) ?Tag {
+ const normalized = normalize(name);
+ if (namespace) |ns| {
+ const normalized_ns = normalize(ns);
+ if (mem.eql(u8, normalized_ns, "gnu")) {
+ return fromStringGnu(normalized);
+ }
+ return null;
+ }
+ const decls = @typeInfo(attributes).Struct.decls;
+ inline for (decls, 0..) |decl, i| {
+ if (@hasDecl(@field(attributes, decl.name), "c2x")) {
+ if (mem.eql(u8, @field(attributes, decl.name).c2x, normalized)) {
+ return @enumFromInt(i);
+ }
+ }
+ }
+ return null;
+}
+
+fn fromStringDeclspec(name: []const u8) ?Tag {
+ const decls = @typeInfo(attributes).Struct.decls;
+ inline for (decls, 0..) |decl, i| {
+ if (@hasDecl(@field(attributes, decl.name), "declspec")) {
+ if (mem.eql(u8, @field(attributes, decl.name).declspec, name)) {
+ return @enumFromInt(i);
+ }
+ }
+ }
+ return null;
+}
+
+fn normalize(name: []const u8) []const u8 {
+ if (name.len >= 4 and mem.startsWith(u8, name, "__") and mem.endsWith(u8, name, "__")) {
+ return name[2 .. name.len - 2];
+ }
+ return name;
+}
+
+fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {
+ const strings_top = p.strings.items.len;
+ defer p.strings.items.len = strings_top;
+
+ try p.strings.writer().print("attribute '{s}' ignored on {s}", .{ @tagName(attr), context });
+ const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+ try p.errStr(.ignored_attribute, tok, str);
+}
+
+pub const applyParameterAttributes = applyVariableAttributes;
+pub fn applyVariableAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
+ const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+ p.attr_application_buf.items.len = 0;
+ var base_ty = ty;
+ if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
+ var common = false;
+ var nocommon = false;
+ for (attrs, toks) |attr, tok| switch (attr.tag) {
+ // zig fmt: off
+ .alias, .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .weak, .used,
+ .noinit, .retain, .persistent, .section, .mode, .asm_label,
+ => try p.attr_application_buf.append(p.gpa, attr),
+ // zig fmt: on
+ .common => if (nocommon) {
+ try p.errTok(.ignore_common, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ common = true;
+ },
+ .nocommon => if (common) {
+ try p.errTok(.ignore_nocommon, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ nocommon = true;
+ },
+ .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
+ .aligned => try attr.applyAligned(p, base_ty, tag),
+ .nonstring => if (!base_ty.isArray() or !(base_ty.is(.char) or base_ty.is(.uchar) or base_ty.is(.schar))) {
+ try p.errStr(.non_string_ignored, tok, try p.typeStr(ty));
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ },
+ .uninitialized => if (p.func.ty == null) {
+ try p.errStr(.local_variable_attribute, tok, "uninitialized");
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ },
+ .cleanup => if (p.func.ty == null) {
+ try p.errStr(.local_variable_attribute, tok, "cleanup");
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ },
+ .alloc_size,
+ .copy,
+ .tls_model,
+ .visibility,
+ => std.debug.panic("apply variable attribute {s}", .{@tagName(attr.tag)}),
+ else => try ignoredAttrErr(p, tok, attr.tag, "variables"),
+ };
+ const existing = ty.getAttributes();
+ if (existing.len == 0 and p.attr_application_buf.items.len == 0) return base_ty;
+ if (existing.len == 0) return base_ty.withAttributes(p.arena, p.attr_application_buf.items);
+
+ const attributed_type = try Type.Attributed.create(p.arena, base_ty, existing, p.attr_application_buf.items);
+ return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } };
+}
+
+pub fn applyFieldAttributes(p: *Parser, field_ty: *Type, attr_buf_start: usize) ![]const Attribute {
+ const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+ p.attr_application_buf.items.len = 0;
+ for (attrs, toks) |attr, tok| switch (attr.tag) {
+ // zig fmt: off
+ .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
+ => try p.attr_application_buf.append(p.gpa, attr),
+ // zig fmt: on
+ .vector_size => try attr.applyVectorSize(p, tok, field_ty),
+ .aligned => try attr.applyAligned(p, field_ty.*, null),
+ else => try ignoredAttrErr(p, tok, attr.tag, "fields"),
+ };
+ if (p.attr_application_buf.items.len == 0) return &[0]Attribute{};
+ return p.arena.dupe(Attribute, p.attr_application_buf.items);
+}
+
+pub fn applyTypeAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
+ const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+ p.attr_application_buf.items.len = 0;
+ var base_ty = ty;
+ if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
+ for (attrs, toks) |attr, tok| switch (attr.tag) {
+ // zig fmt: off
+ .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
+ => try p.attr_application_buf.append(p.gpa, attr),
+ // zig fmt: on
+ .transparent_union => try attr.applyTransparentUnion(p, tok, base_ty),
+ .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
+ .aligned => try attr.applyAligned(p, base_ty, tag),
+ .designated_init => if (base_ty.is(.@"struct")) {
+ try p.attr_application_buf.append(p.gpa, attr);
+ } else {
+ try p.errTok(.designated_init_invalid, tok);
+ },
+ .alloc_size,
+ .copy,
+ .scalar_storage_order,
+ .nonstring,
+ => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
+ else => try ignoredAttrErr(p, tok, attr.tag, "types"),
+ };
+
+ const existing = ty.getAttributes();
+ // TODO: the alignment annotation on a type should override
+ // the decl it refers to. This might not be true for others. Maybe bug.
+
+ // if there are annotations on this type def use those.
+ if (p.attr_application_buf.items.len > 0) {
+ return try base_ty.withAttributes(p.arena, p.attr_application_buf.items);
+ } else if (existing.len > 0) {
+ // else use the ones on the typedef decl we were refering to.
+ return try base_ty.withAttributes(p.arena, existing);
+ }
+ return base_ty;
+}
+
+pub fn applyFunctionAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
+ const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+ p.attr_application_buf.items.len = 0;
+ var base_ty = ty;
+ if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
+ var hot = false;
+ var cold = false;
+ var @"noinline" = false;
+ var always_inline = false;
+ for (attrs, toks) |attr, tok| switch (attr.tag) {
+ // zig fmt: off
+ .noreturn, .unused, .used, .warning, .deprecated, .unavailable, .weak, .pure, .leaf,
+ .@"const", .warn_unused_result, .section, .returns_nonnull, .returns_twice, .@"error",
+ .externally_visible, .retain, .flatten, .gnu_inline, .alias, .asm_label, .nodiscard,
+ .reproducible, .unsequenced,
+ => try p.attr_application_buf.append(p.gpa, attr),
+ // zig fmt: on
+ .hot => if (cold) {
+ try p.errTok(.ignore_hot, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ hot = true;
+ },
+ .cold => if (hot) {
+ try p.errTok(.ignore_cold, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ cold = true;
+ },
+ .always_inline => if (@"noinline") {
+ try p.errTok(.ignore_always_inline, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ always_inline = true;
+ },
+ .@"noinline" => if (always_inline) {
+ try p.errTok(.ignore_noinline, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ @"noinline" = true;
+ },
+ .aligned => try attr.applyAligned(p, base_ty, null),
+ .format => try attr.applyFormat(p, base_ty),
+ .calling_convention => switch (attr.args.calling_convention.cc) {
+ .C => continue,
+ .stdcall, .thiscall => switch (p.comp.target.cpu.arch) {
+ .x86 => try p.attr_application_buf.append(p.gpa, attr),
+ else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
+ },
+ .vectorcall => switch (p.comp.target.cpu.arch) {
+ .x86, .aarch64, .aarch64_be, .aarch64_32 => try p.attr_application_buf.append(p.gpa, attr),
+ else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
+ },
+ },
+ .access,
+ .alloc_align,
+ .alloc_size,
+ .artificial,
+ .assume_aligned,
+ .constructor,
+ .copy,
+ .destructor,
+ .format_arg,
+ .ifunc,
+ .interrupt,
+ .interrupt_handler,
+ .malloc,
+ .no_address_safety_analysis,
+ .no_icf,
+ .no_instrument_function,
+ .no_profile_instrument_function,
+ .no_reorder,
+ .no_sanitize,
+ .no_sanitize_address,
+ .no_sanitize_coverage,
+ .no_sanitize_thread,
+ .no_sanitize_undefined,
+ .no_split_stack,
+ .no_stack_limit,
+ .no_stack_protector,
+ .noclone,
+ .noipa,
+ // .nonnull,
+ .noplt,
+ // .optimize,
+ .patchable_function_entry,
+ .sentinel,
+ .simd,
+ .stack_protect,
+ .symver,
+ .target,
+ .target_clones,
+ .visibility,
+ .weakref,
+ .zero_call_used_regs,
+ => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
+ else => try ignoredAttrErr(p, tok, attr.tag, "functions"),
+ };
+ return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+pub fn applyLabelAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
+ const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+ p.attr_application_buf.items.len = 0;
+ var hot = false;
+ var cold = false;
+ for (attrs, toks) |attr, tok| switch (attr.tag) {
+ .unused => try p.attr_application_buf.append(p.gpa, attr),
+ .hot => if (cold) {
+ try p.errTok(.ignore_hot, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ hot = true;
+ },
+ .cold => if (hot) {
+ try p.errTok(.ignore_cold, tok);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ cold = true;
+ },
+ else => try ignoredAttrErr(p, tok, attr.tag, "labels"),
+ };
+ return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+pub fn applyStatementAttributes(p: *Parser, ty: Type, expr_start: TokenIndex, attr_buf_start: usize) !Type {
+ const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+ p.attr_application_buf.items.len = 0;
+ for (attrs, toks) |attr, tok| switch (attr.tag) {
+ .fallthrough => if (p.tok_ids[p.tok_i] != .keyword_case and p.tok_ids[p.tok_i] != .keyword_default) {
+ // TODO: this condition is not completely correct; the last statement of a compound
+ // statement is also valid if it precedes a switch label (so intervening '}' are ok,
+ // but only if they close a compound statement)
+ try p.errTok(.invalid_fallthrough, expr_start);
+ } else {
+ try p.attr_application_buf.append(p.gpa, attr);
+ },
+ else => try p.errStr(.cannot_apply_attribute_to_statement, tok, @tagName(attr.tag)),
+ };
+ return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+pub fn applyEnumeratorAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
+ const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+ p.attr_application_buf.items.len = 0;
+ for (attrs, toks) |attr, tok| switch (attr.tag) {
+ .deprecated, .unavailable => try p.attr_application_buf.append(p.gpa, attr),
+ else => try ignoredAttrErr(p, tok, attr.tag, "enums"),
+ };
+ return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+fn applyAligned(attr: Attribute, p: *Parser, ty: Type, tag: ?Diagnostics.Tag) !void {
+ const base = ty.canonicalize(.standard);
+ if (attr.args.aligned.alignment) |alignment| alignas: {
+ if (attr.syntax != .keyword) break :alignas;
+
+ const align_tok = attr.args.aligned.__name_tok;
+ if (tag) |t| try p.errTok(t, align_tok);
+
+ const default_align = base.alignof(p.comp);
+ if (ty.isFunc()) {
+ try p.errTok(.alignas_on_func, align_tok);
+ } else if (alignment.requested < default_align) {
+ try p.errExtra(.minimum_alignment, align_tok, .{ .unsigned = default_align });
+ }
+ }
+ try p.attr_application_buf.append(p.gpa, attr);
+}
+
+fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type) !void {
+ const union_ty = ty.get(.@"union") orelse {
+ return p.errTok(.transparent_union_wrong_type, tok);
+ };
+ // TODO validate union defined at end
+ if (union_ty.data.record.isIncomplete()) return;
+ const fields = union_ty.data.record.fields;
+ if (fields.len == 0) {
+ return p.errTok(.transparent_union_one_field, tok);
+ }
+ const first_field_size = fields[0].ty.bitSizeof(p.comp).?;
+ for (fields[1..]) |field| {
+ const field_size = field.ty.bitSizeof(p.comp).?;
+ if (field_size == first_field_size) continue;
+ const mapper = p.comp.string_interner.getSlowTypeMapper();
+ const str = try std.fmt.allocPrint(p.comp.diag.arena.allocator(), "'{s}' ({d}", .{ mapper.lookup(field.name), field_size });
+ try p.errStr(.transparent_union_size, field.name_tok, str);
+ return p.errExtra(.transparent_union_size_note, fields[0].name_tok, .{ .unsigned = first_field_size });
+ }
+
+ try p.attr_application_buf.append(p.gpa, attr);
+}
+
+fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !void {
+ if (!(ty.isInt() or ty.isFloat()) or !ty.isReal()) {
+ const orig_ty = try p.typeStr(ty.*);
+ ty.* = Type.invalid;
+ return p.errStr(.invalid_vec_elem_ty, tok, orig_ty);
+ }
+ const vec_bytes = attr.args.vector_size.bytes;
+ const ty_size = ty.sizeof(p.comp).?;
+ if (vec_bytes % ty_size != 0) {
+ return p.errTok(.vec_size_not_multiple, tok);
+ }
+ const vec_size = vec_bytes / ty_size;
+
+ const arr_ty = try p.arena.create(Type.Array);
+ arr_ty.* = .{ .elem = ty.*, .len = vec_size };
+ ty.* = Type{
+ .specifier = .vector,
+ .data = .{ .array = arr_ty },
+ };
+}
+
+fn applyFormat(attr: Attribute, p: *Parser, ty: Type) !void {
+ // TODO validate
+ _ = ty;
+ try p.attr_application_buf.append(p.gpa, attr);
+}
deps/aro/Builtins.zig
@@ -0,0 +1,337 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Type = @import("Type.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const TypeDescription = @import("builtins/TypeDescription.zig");
+const target_util = @import("target.zig");
+const StringId = @import("StringInterner.zig").StringId;
+const LangOpts = @import("LangOpts.zig");
+const Parser = @import("Parser.zig");
+
+const Builtins = @This();
+
+const Expanded = struct {
+ ty: Type,
+ builtin: BuiltinFunction,
+};
+
+const NameToTypeMap = std.StringHashMapUnmanaged(Type);
+
+_name_to_type_map: NameToTypeMap = .{},
+
+pub fn deinit(b: *Builtins, gpa: std.mem.Allocator) void {
+ b._name_to_type_map.deinit(gpa);
+}
+
+fn specForSize(comp: *const Compilation, size_bits: u32) Type.Builder.Specifier {
+ var ty = Type{ .specifier = .short };
+ if (ty.sizeof(comp).? * 8 == size_bits) return .short;
+
+ ty.specifier = .int;
+ if (ty.sizeof(comp).? * 8 == size_bits) return .int;
+
+ ty.specifier = .long;
+ if (ty.sizeof(comp).? * 8 == size_bits) return .long;
+
+ ty.specifier = .long_long;
+ if (ty.sizeof(comp).? * 8 == size_bits) return .long_long;
+
+ unreachable;
+}
+
+fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *const Compilation, allocator: std.mem.Allocator) !Type {
+ var builder: Type.Builder = .{ .error_on_invalid = true };
+ var require_native_int32 = false;
+ var require_native_int64 = false;
+ for (desc.prefix) |prefix| {
+ switch (prefix) {
+ .L => builder.combine(undefined, .long, 0) catch unreachable,
+ .LL => {
+ builder.combine(undefined, .long, 0) catch unreachable;
+ builder.combine(undefined, .long, 0) catch unreachable;
+ },
+ .LLL => {
+ switch (builder.specifier) {
+ .none => builder.specifier = .int128,
+ .signed => builder.specifier = .sint128,
+ .unsigned => builder.specifier = .uint128,
+ else => unreachable,
+ }
+ },
+ .Z => require_native_int32 = true,
+ .W => require_native_int64 = true,
+ .N => {
+ std.debug.assert(desc.spec == .i);
+ if (!target_util.isLP64(comp.target)) {
+ builder.combine(undefined, .long, 0) catch unreachable;
+ }
+ },
+ .O => {
+ builder.combine(undefined, .long, 0) catch unreachable;
+ if (comp.target.os.tag != .opencl) {
+ builder.combine(undefined, .long, 0) catch unreachable;
+ }
+ },
+ .S => builder.combine(undefined, .signed, 0) catch unreachable,
+ .U => builder.combine(undefined, .unsigned, 0) catch unreachable,
+ .I => {
+ // Todo: compile-time constant integer
+ },
+ }
+ }
+ switch (desc.spec) {
+ .v => builder.combine(undefined, .void, 0) catch unreachable,
+ .b => builder.combine(undefined, .bool, 0) catch unreachable,
+ .c => builder.combine(undefined, .char, 0) catch unreachable,
+ .s => builder.combine(undefined, .short, 0) catch unreachable,
+ .i => {
+ if (require_native_int32) {
+ builder.specifier = specForSize(comp, 32);
+ } else if (require_native_int64) {
+ builder.specifier = specForSize(comp, 64);
+ } else {
+ switch (builder.specifier) {
+ .int128, .sint128, .uint128 => {},
+ else => builder.combine(undefined, .int, 0) catch unreachable,
+ }
+ }
+ },
+ .h => builder.combine(undefined, .fp16, 0) catch unreachable,
+ .x => {
+ // Todo: _Float16
+ return .{ .specifier = .invalid };
+ },
+ .y => {
+ // Todo: __bf16
+ return .{ .specifier = .invalid };
+ },
+ .f => builder.combine(undefined, .float, 0) catch unreachable,
+ .d => {
+ if (builder.specifier == .long_long) {
+ builder.specifier = .float128;
+ } else {
+ builder.combine(undefined, .double, 0) catch unreachable;
+ }
+ },
+ .z => {
+ std.debug.assert(builder.specifier == .none);
+ builder.specifier = Type.Builder.fromType(comp.types.size);
+ },
+ .w => {
+ std.debug.assert(builder.specifier == .none);
+ builder.specifier = Type.Builder.fromType(comp.types.wchar);
+ },
+ .F => {
+ std.debug.assert(builder.specifier == .none);
+ builder.specifier = Type.Builder.fromType(comp.types.ns_constant_string.ty);
+ },
+ .a => {
+ std.debug.assert(builder.specifier == .none);
+ std.debug.assert(desc.suffix.len == 0);
+ builder.specifier = Type.Builder.fromType(comp.types.va_list);
+ },
+ .A => {
+ std.debug.assert(builder.specifier == .none);
+ std.debug.assert(desc.suffix.len == 0);
+ var va_list = comp.types.va_list;
+ if (va_list.isArray()) va_list.decayArray();
+ builder.specifier = Type.Builder.fromType(va_list);
+ },
+ .V => |element_count| {
+ std.debug.assert(desc.suffix.len == 0);
+ const child_desc = it.next().?;
+ const child_ty = try createType(child_desc, undefined, comp, allocator);
+ const arr_ty = try allocator.create(Type.Array);
+ arr_ty.* = .{
+ .len = element_count,
+ .elem = child_ty,
+ };
+ const vector_ty = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
+ builder.specifier = Type.Builder.fromType(vector_ty);
+ },
+ .q => {
+ // Todo: scalable vector
+ return .{ .specifier = .invalid };
+ },
+ .E => {
+ // Todo: ext_vector (OpenCL vector)
+ return .{ .specifier = .invalid };
+ },
+ .X => |child| {
+ builder.combine(undefined, .complex, 0) catch unreachable;
+ switch (child) {
+ .float => builder.combine(undefined, .float, 0) catch unreachable,
+ .double => builder.combine(undefined, .double, 0) catch unreachable,
+ .longdouble => {
+ builder.combine(undefined, .long, 0) catch unreachable;
+ builder.combine(undefined, .double, 0) catch unreachable;
+ },
+ }
+ },
+ .Y => {
+ std.debug.assert(builder.specifier == .none);
+ std.debug.assert(desc.suffix.len == 0);
+ builder.specifier = Type.Builder.fromType(comp.types.ptrdiff);
+ },
+ .P => {
+ std.debug.assert(builder.specifier == .none);
+ if (comp.types.file.specifier == .invalid) {
+ return comp.types.file;
+ }
+ builder.specifier = Type.Builder.fromType(comp.types.file);
+ },
+ .J => {
+ std.debug.assert(builder.specifier == .none);
+ std.debug.assert(desc.suffix.len == 0);
+ if (comp.types.jmp_buf.specifier == .invalid) {
+ return comp.types.jmp_buf;
+ }
+ builder.specifier = Type.Builder.fromType(comp.types.jmp_buf);
+ },
+ .SJ => {
+ std.debug.assert(builder.specifier == .none);
+ std.debug.assert(desc.suffix.len == 0);
+ if (comp.types.sigjmp_buf.specifier == .invalid) {
+ return comp.types.sigjmp_buf;
+ }
+ builder.specifier = Type.Builder.fromType(comp.types.sigjmp_buf);
+ },
+ .K => {
+ std.debug.assert(builder.specifier == .none);
+ if (comp.types.ucontext_t.specifier == .invalid) {
+ return comp.types.ucontext_t;
+ }
+ builder.specifier = Type.Builder.fromType(comp.types.ucontext_t);
+ },
+ .p => {
+ std.debug.assert(builder.specifier == .none);
+ std.debug.assert(desc.suffix.len == 0);
+ builder.specifier = Type.Builder.fromType(comp.types.pid_t);
+ },
+ .@"!" => return .{ .specifier = .invalid },
+ }
+ for (desc.suffix) |suffix| {
+ switch (suffix) {
+ .@"*" => |address_space| {
+ _ = address_space; // TODO: handle address space
+ const elem_ty = try allocator.create(Type);
+ elem_ty.* = builder.finish(undefined) catch unreachable;
+ const ty = Type{
+ .specifier = .pointer,
+ .data = .{ .sub_type = elem_ty },
+ };
+ builder.qual = .{};
+ builder.specifier = Type.Builder.fromType(ty);
+ },
+ .C => builder.qual.@"const" = 0,
+ .D => builder.qual.@"volatile" = 0,
+ .R => builder.qual.restrict = 0,
+ }
+ }
+ return builder.finish(undefined) catch unreachable;
+}
+
+fn createBuiltin(comp: *const Compilation, builtin: BuiltinFunction, type_arena: std.mem.Allocator) !Type {
+ var it = TypeDescription.TypeIterator.init(builtin.param_str);
+
+ const ret_ty_desc = it.next().?;
+ if (ret_ty_desc.spec == .@"!") {
+ // Todo: handle target-dependent definition
+ }
+ const ret_ty = try createType(ret_ty_desc, &it, comp, type_arena);
+ var param_count: usize = 0;
+ var params: [BuiltinFunction.MaxParamCount]Type.Func.Param = undefined;
+ while (it.next()) |desc| : (param_count += 1) {
+ params[param_count] = .{ .name_tok = 0, .ty = try createType(desc, &it, comp, type_arena), .name = .empty };
+ }
+
+ const duped_params = try type_arena.dupe(Type.Func.Param, params[0..param_count]);
+ const func = try type_arena.create(Type.Func);
+
+ func.* = .{
+ .return_type = ret_ty,
+ .params = duped_params,
+ };
+ return .{
+ .specifier = if (builtin.isVarArgs()) .var_args_func else .func,
+ .data = .{ .func = func },
+ };
+}
+
+/// Asserts that the builtin has already been created
+pub fn lookup(b: *const Builtins, name: []const u8) Expanded {
+ @setEvalBranchQuota(10_000);
+ const builtin = BuiltinFunction.fromTag(std.meta.stringToEnum(BuiltinFunction.Tag, name).?);
+ const ty = b._name_to_type_map.get(name).?;
+ return .{
+ .builtin = builtin,
+ .ty = ty,
+ };
+}
+
+pub fn getOrCreate(b: *Builtins, comp: *Compilation, name: []const u8, type_arena: std.mem.Allocator) !?Expanded {
+ const ty = b._name_to_type_map.get(name) orelse {
+ @setEvalBranchQuota(10_000);
+ const tag = std.meta.stringToEnum(BuiltinFunction.Tag, name) orelse return null;
+ const builtin = BuiltinFunction.fromTag(tag);
+ if (!comp.hasBuiltinFunction(builtin)) return null;
+
+ try b._name_to_type_map.ensureUnusedCapacity(comp.gpa, 1);
+ const ty = try createBuiltin(comp, builtin, type_arena);
+ b._name_to_type_map.putAssumeCapacity(name, ty);
+
+ return .{
+ .builtin = builtin,
+ .ty = ty,
+ };
+ };
+ const builtin = BuiltinFunction.fromTag(std.meta.stringToEnum(BuiltinFunction.Tag, name).?);
+ return .{
+ .builtin = builtin,
+ .ty = ty,
+ };
+}
+
+test "All builtins" {
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+ _ = try comp.generateBuiltinMacros();
+ var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
+ defer arena.deinit();
+
+ const type_arena = arena.allocator();
+
+ for (0..@typeInfo(BuiltinFunction.Tag).Enum.fields.len) |i| {
+ const tag: BuiltinFunction.Tag = @enumFromInt(i);
+ const name = @tagName(tag);
+ if (try comp.builtins.getOrCreate(&comp, name, type_arena)) |func_ty| {
+ const get_again = (try comp.builtins.getOrCreate(&comp, name, std.testing.failing_allocator)).?;
+ const found_by_lookup = comp.builtins.lookup(name);
+ try std.testing.expectEqual(func_ty.builtin.tag, get_again.builtin.tag);
+ try std.testing.expectEqual(func_ty.builtin.tag, found_by_lookup.builtin.tag);
+ }
+ }
+}
+
+test "Allocation failures" {
+ const Test = struct {
+ fn testOne(allocator: std.mem.Allocator) !void {
+ var comp = Compilation.init(allocator);
+ defer comp.deinit();
+ _ = try comp.generateBuiltinMacros();
+ var arena = std.heap.ArenaAllocator.init(comp.gpa);
+ defer arena.deinit();
+
+ const type_arena = arena.allocator();
+
+ const num_builtins = 40;
+ for (0..num_builtins) |i| {
+ const tag: BuiltinFunction.Tag = @enumFromInt(i);
+ const name = @tagName(tag);
+ _ = try comp.builtins.getOrCreate(&comp, name, type_arena);
+ }
+ }
+ };
+
+ try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.testOne, .{});
+}
deps/aro/CharInfo.zig
@@ -0,0 +1,487 @@
+//! This module provides functions for classifying characters according to
+//! various C standards. All classification routines *do not* consider
+//! characters from the basic character set; it is assumed those will be
+//! checked separately
+
+const assert = @import("std").debug.assert;
+
+/// C11 Standard Annex D
+pub fn isC11IdChar(codepoint: u21) bool {
+ assert(codepoint > 0x7F);
+ return switch (codepoint) {
+ // 1
+ 0x00A8,
+ 0x00AA,
+ 0x00AD,
+ 0x00AF,
+ 0x00B2...0x00B5,
+ 0x00B7...0x00BA,
+ 0x00BC...0x00BE,
+ 0x00C0...0x00D6,
+ 0x00D8...0x00F6,
+ 0x00F8...0x00FF,
+
+ // 2
+ 0x0100...0x167F,
+ 0x1681...0x180D,
+ 0x180F...0x1FFF,
+
+ // 3
+ 0x200B...0x200D,
+ 0x202A...0x202E,
+ 0x203F...0x2040,
+ 0x2054,
+ 0x2060...0x206F,
+
+ // 4
+ 0x2070...0x218F,
+ 0x2460...0x24FF,
+ 0x2776...0x2793,
+ 0x2C00...0x2DFF,
+ 0x2E80...0x2FFF,
+
+ // 5
+ 0x3004...0x3007,
+ 0x3021...0x302F,
+ 0x3031...0x303F,
+
+ // 6
+ 0x3040...0xD7FF,
+
+ // 7
+ 0xF900...0xFD3D,
+ 0xFD40...0xFDCF,
+ 0xFDF0...0xFE44,
+ 0xFE47...0xFFFD,
+
+ // 8
+ 0x10000...0x1FFFD,
+ 0x20000...0x2FFFD,
+ 0x30000...0x3FFFD,
+ 0x40000...0x4FFFD,
+ 0x50000...0x5FFFD,
+ 0x60000...0x6FFFD,
+ 0x70000...0x7FFFD,
+ 0x80000...0x8FFFD,
+ 0x90000...0x9FFFD,
+ 0xA0000...0xAFFFD,
+ 0xB0000...0xBFFFD,
+ 0xC0000...0xCFFFD,
+ 0xD0000...0xDFFFD,
+ 0xE0000...0xEFFFD,
+ => true,
+ else => false,
+ };
+}
+
+/// C99 Standard Annex D
+pub fn isC99IdChar(codepoint: u21) bool {
+ assert(codepoint > 0x7F);
+ return switch (codepoint) {
+ // Latin
+ 0x00AA,
+ 0x00BA,
+ 0x00C0...0x00D6,
+ 0x00D8...0x00F6,
+ 0x00F8...0x01F5,
+ 0x01FA...0x0217,
+ 0x0250...0x02A8,
+ 0x1E00...0x1E9B,
+ 0x1EA0...0x1EF9,
+ 0x207F,
+
+ // Greek
+ 0x0386,
+ 0x0388...0x038A,
+ 0x038C,
+ 0x038E...0x03A1,
+ 0x03A3...0x03CE,
+ 0x03D0...0x03D6,
+ 0x03DA,
+ 0x03DC,
+ 0x03DE,
+ 0x03E0,
+ 0x03E2...0x03F3,
+ 0x1F00...0x1F15,
+ 0x1F18...0x1F1D,
+ 0x1F20...0x1F45,
+ 0x1F48...0x1F4D,
+ 0x1F50...0x1F57,
+ 0x1F59,
+ 0x1F5B,
+ 0x1F5D,
+ 0x1F5F...0x1F7D,
+ 0x1F80...0x1FB4,
+ 0x1FB6...0x1FBC,
+ 0x1FC2...0x1FC4,
+ 0x1FC6...0x1FCC,
+ 0x1FD0...0x1FD3,
+ 0x1FD6...0x1FDB,
+ 0x1FE0...0x1FEC,
+ 0x1FF2...0x1FF4,
+ 0x1FF6...0x1FFC,
+
+ // Cyrillic
+ 0x0401...0x040C,
+ 0x040E...0x044F,
+ 0x0451...0x045C,
+ 0x045E...0x0481,
+ 0x0490...0x04C4,
+ 0x04C7...0x04C8,
+ 0x04CB...0x04CC,
+ 0x04D0...0x04EB,
+ 0x04EE...0x04F5,
+ 0x04F8...0x04F9,
+
+ // Armenian
+ 0x0531...0x0556,
+ 0x0561...0x0587,
+
+ // Hebrew
+ 0x05B0...0x05B9,
+ 0x05BB...0x05BD,
+ 0x05BF,
+ 0x05C1...0x05C2,
+ 0x05D0...0x05EA,
+ 0x05F0...0x05F2,
+
+ // Arabic
+ 0x0621...0x063A,
+ 0x0640...0x0652,
+ 0x0670...0x06B7,
+ 0x06BA...0x06BE,
+ 0x06C0...0x06CE,
+ 0x06D0...0x06DC,
+ 0x06E5...0x06E8,
+ 0x06EA...0x06ED,
+
+ // Devanagari
+ 0x0901...0x0903,
+ 0x0905...0x0939,
+ 0x093E...0x094D,
+ 0x0950...0x0952,
+ 0x0958...0x0963,
+
+ // Bengali
+ 0x0981...0x0983,
+ 0x0985...0x098C,
+ 0x098F...0x0990,
+ 0x0993...0x09A8,
+ 0x09AA...0x09B0,
+ 0x09B2,
+ 0x09B6...0x09B9,
+ 0x09BE...0x09C4,
+ 0x09C7...0x09C8,
+ 0x09CB...0x09CD,
+ 0x09DC...0x09DD,
+ 0x09DF...0x09E3,
+ 0x09F0...0x09F1,
+
+ // Gurmukhi
+ 0x0A02,
+ 0x0A05...0x0A0A,
+ 0x0A0F...0x0A10,
+ 0x0A13...0x0A28,
+ 0x0A2A...0x0A30,
+ 0x0A32...0x0A33,
+ 0x0A35...0x0A36,
+ 0x0A38...0x0A39,
+ 0x0A3E...0x0A42,
+ 0x0A47...0x0A48,
+ 0x0A4B...0x0A4D,
+ 0x0A59...0x0A5C,
+ 0x0A5E,
+ 0x0A74,
+
+ // Gujarati
+ 0x0A81...0x0A83,
+ 0x0A85...0x0A8B,
+ 0x0A8D,
+ 0x0A8F...0x0A91,
+ 0x0A93...0x0AA8,
+ 0x0AAA...0x0AB0,
+ 0x0AB2...0x0AB3,
+ 0x0AB5...0x0AB9,
+ 0x0ABD...0x0AC5,
+ 0x0AC7...0x0AC9,
+ 0x0ACB...0x0ACD,
+ 0x0AD0,
+ 0x0AE0,
+
+ // Oriya
+ 0x0B01...0x0B03,
+ 0x0B05...0x0B0C,
+ 0x0B0F...0x0B10,
+ 0x0B13...0x0B28,
+ 0x0B2A...0x0B30,
+ 0x0B32...0x0B33,
+ 0x0B36...0x0B39,
+ 0x0B3E...0x0B43,
+ 0x0B47...0x0B48,
+ 0x0B4B...0x0B4D,
+ 0x0B5C...0x0B5D,
+ 0x0B5F...0x0B61,
+
+ // Tamil
+ 0x0B82...0x0B83,
+ 0x0B85...0x0B8A,
+ 0x0B8E...0x0B90,
+ 0x0B92...0x0B95,
+ 0x0B99...0x0B9A,
+ 0x0B9C,
+ 0x0B9E...0x0B9F,
+ 0x0BA3...0x0BA4,
+ 0x0BA8...0x0BAA,
+ 0x0BAE...0x0BB5,
+ 0x0BB7...0x0BB9,
+ 0x0BBE...0x0BC2,
+ 0x0BC6...0x0BC8,
+ 0x0BCA...0x0BCD,
+
+ // Telugu
+ 0x0C01...0x0C03,
+ 0x0C05...0x0C0C,
+ 0x0C0E...0x0C10,
+ 0x0C12...0x0C28,
+ 0x0C2A...0x0C33,
+ 0x0C35...0x0C39,
+ 0x0C3E...0x0C44,
+ 0x0C46...0x0C48,
+ 0x0C4A...0x0C4D,
+ 0x0C60...0x0C61,
+
+ // Kannada
+ 0x0C82...0x0C83,
+ 0x0C85...0x0C8C,
+ 0x0C8E...0x0C90,
+ 0x0C92...0x0CA8,
+ 0x0CAA...0x0CB3,
+ 0x0CB5...0x0CB9,
+ 0x0CBE...0x0CC4,
+ 0x0CC6...0x0CC8,
+ 0x0CCA...0x0CCD,
+ 0x0CDE,
+ 0x0CE0...0x0CE1,
+
+ // Malayalam
+ 0x0D02...0x0D03,
+ 0x0D05...0x0D0C,
+ 0x0D0E...0x0D10,
+ 0x0D12...0x0D28,
+ 0x0D2A...0x0D39,
+ 0x0D3E...0x0D43,
+ 0x0D46...0x0D48,
+ 0x0D4A...0x0D4D,
+ 0x0D60...0x0D61,
+
+ // Thai (excluding digits 0x0E50...0x0E59; originally 0x0E01...0x0E3A and 0x0E40...0x0E5B
+ 0x0E01...0x0E3A,
+ 0x0E40...0x0E4F,
+ 0x0E5A...0x0E5B,
+
+ // Lao
+ 0x0E81...0x0E82,
+ 0x0E84,
+ 0x0E87...0x0E88,
+ 0x0E8A,
+ 0x0E8D,
+ 0x0E94...0x0E97,
+ 0x0E99...0x0E9F,
+ 0x0EA1...0x0EA3,
+ 0x0EA5,
+ 0x0EA7,
+ 0x0EAA...0x0EAB,
+ 0x0EAD...0x0EAE,
+ 0x0EB0...0x0EB9,
+ 0x0EBB...0x0EBD,
+ 0x0EC0...0x0EC4,
+ 0x0EC6,
+ 0x0EC8...0x0ECD,
+ 0x0EDC...0x0EDD,
+
+ // Tibetan
+ 0x0F00,
+ 0x0F18...0x0F19,
+ 0x0F35,
+ 0x0F37,
+ 0x0F39,
+ 0x0F3E...0x0F47,
+ 0x0F49...0x0F69,
+ 0x0F71...0x0F84,
+ 0x0F86...0x0F8B,
+ 0x0F90...0x0F95,
+ 0x0F97,
+ 0x0F99...0x0FAD,
+ 0x0FB1...0x0FB7,
+ 0x0FB9,
+
+ // Georgian
+ 0x10A0...0x10C5,
+ 0x10D0...0x10F6,
+
+ // Hiragana
+ 0x3041...0x3093,
+ 0x309B...0x309C,
+
+ // Katakana
+ 0x30A1...0x30F6,
+ 0x30FB...0x30FC,
+
+ // Bopomofo
+ 0x3105...0x312C,
+
+ // CJK Unified Ideographs
+ 0x4E00...0x9FA5,
+
+ // Hangul
+ 0xAC00...0xD7A3,
+
+ // Digits
+ 0x0660...0x0669,
+ 0x06F0...0x06F9,
+ 0x0966...0x096F,
+ 0x09E6...0x09EF,
+ 0x0A66...0x0A6F,
+ 0x0AE6...0x0AEF,
+ 0x0B66...0x0B6F,
+ 0x0BE7...0x0BEF,
+ 0x0C66...0x0C6F,
+ 0x0CE6...0x0CEF,
+ 0x0D66...0x0D6F,
+ 0x0E50...0x0E59,
+ 0x0ED0...0x0ED9,
+ 0x0F20...0x0F33,
+
+ // Special characters
+ 0x00B5,
+ 0x00B7,
+ 0x02B0...0x02B8,
+ 0x02BB,
+ 0x02BD...0x02C1,
+ 0x02D0...0x02D1,
+ 0x02E0...0x02E4,
+ 0x037A,
+ 0x0559,
+ 0x093D,
+ 0x0B3D,
+ 0x1FBE,
+ 0x203F...0x2040,
+ 0x2102,
+ 0x2107,
+ 0x210A...0x2113,
+ 0x2115,
+ 0x2118...0x211D,
+ 0x2124,
+ 0x2126,
+ 0x2128,
+ 0x212A...0x2131,
+ 0x2133...0x2138,
+ 0x2160...0x2182,
+ 0x3005...0x3007,
+ 0x3021...0x3029,
+ => true,
+ else => false,
+ };
+}
+
+/// C11 standard Annex D
+pub fn isC11DisallowedInitialIdChar(codepoint: u21) bool {
+ assert(codepoint > 0x7F);
+ return switch (codepoint) {
+ 0x0300...0x036F,
+ 0x1DC0...0x1DFF,
+ 0x20D0...0x20FF,
+ 0xFE20...0xFE2F,
+ => true,
+ else => false,
+ };
+}
+
+/// These are "digit" characters; C99 disallows them as the first
+/// character of an identifier
+pub fn isC99DisallowedInitialIDChar(codepoint: u21) bool {
+ assert(codepoint > 0x7F);
+ return switch (codepoint) {
+ 0x0660...0x0669,
+ 0x06F0...0x06F9,
+ 0x0966...0x096F,
+ 0x09E6...0x09EF,
+ 0x0A66...0x0A6F,
+ 0x0AE6...0x0AEF,
+ 0x0B66...0x0B6F,
+ 0x0BE7...0x0BEF,
+ 0x0C66...0x0C6F,
+ 0x0CE6...0x0CEF,
+ 0x0D66...0x0D6F,
+ 0x0E50...0x0E59,
+ 0x0ED0...0x0ED9,
+ 0x0F20...0x0F33,
+ => true,
+ else => false,
+ };
+}
+
+pub fn isInvisible(codepoint: u21) bool {
+ assert(codepoint > 0x7F);
+ return switch (codepoint) {
+ 0x00ad, // SOFT HYPHEN
+ 0x200b, // ZERO WIDTH SPACE
+ 0x200c, // ZERO WIDTH NON-JOINER
+ 0x200d, // ZERO WIDTH JOINER
+ 0x2060, // WORD JOINER
+ 0x2061, // FUNCTION APPLICATION
+ 0x2062, // INVISIBLE TIMES
+ 0x2063, // INVISIBLE SEPARATOR
+ 0x2064, // INVISIBLE PLUS
+ 0xfeff, // ZERO WIDTH NO-BREAK SPACE
+ => true,
+ else => false,
+ };
+}
+
+/// Checks for identifier characters which resemble non-identifier characters
+pub fn homoglyph(codepoint: u21) ?u21 {
+ assert(codepoint > 0x7F);
+ return switch (codepoint) {
+ 0x01c3 => '!', // LATIN LETTER RETROFLEX CLICK
+ 0x037e => ';', // GREEK QUESTION MARK
+ 0x2212 => '-', // MINUS SIGN
+ 0x2215 => '/', // DIVISION SLASH
+ 0x2216 => '\\', // SET MINUS
+ 0x2217 => '*', // ASTERISK OPERATOR
+ 0x2223 => '|', // DIVIDES
+ 0x2227 => '^', // LOGICAL AND
+ 0x2236 => ':', // RATIO
+ 0x223c => '~', // TILDE OPERATOR
+ 0xa789 => ':', // MODIFIER LETTER COLON
+ 0xff01 => '!', // FULLWIDTH EXCLAMATION MARK
+ 0xff03 => '#', // FULLWIDTH NUMBER SIGN
+ 0xff04 => '$', // FULLWIDTH DOLLAR SIGN
+ 0xff05 => '%', // FULLWIDTH PERCENT SIGN
+ 0xff06 => '&', // FULLWIDTH AMPERSAND
+ 0xff08 => '(', // FULLWIDTH LEFT PARENTHESIS
+ 0xff09 => ')', // FULLWIDTH RIGHT PARENTHESIS
+ 0xff0a => '*', // FULLWIDTH ASTERISK
+ 0xff0b => '+', // FULLWIDTH ASTERISK
+ 0xff0c => ',', // FULLWIDTH COMMA
+ 0xff0d => '-', // FULLWIDTH HYPHEN-MINUS
+ 0xff0e => '.', // FULLWIDTH FULL STOP
+ 0xff0f => '/', // FULLWIDTH SOLIDUS
+ 0xff1a => ':', // FULLWIDTH COLON
+ 0xff1b => ';', // FULLWIDTH SEMICOLON
+ 0xff1c => '<', // FULLWIDTH LESS-THAN SIGN
+ 0xff1d => '=', // FULLWIDTH EQUALS SIGN
+ 0xff1e => '>', // FULLWIDTH GREATER-THAN SIGN
+ 0xff1f => '?', // FULLWIDTH QUESTION MARK
+ 0xff20 => '@', // FULLWIDTH COMMERCIAL AT
+ 0xff3b => '[', // FULLWIDTH LEFT SQUARE BRACKET
+ 0xff3c => '\\', // FULLWIDTH REVERSE SOLIDUS
+ 0xff3d => ']', // FULLWIDTH RIGHT SQUARE BRACKET
+ 0xff3e => '^', // FULLWIDTH CIRCUMFLEX ACCENT
+ 0xff5b => '{', // FULLWIDTH LEFT CURLY BRACKET
+ 0xff5c => '|', // FULLWIDTH VERTICAL LINE
+ 0xff5d => '}', // FULLWIDTH RIGHT CURLY BRACKET
+ 0xff5e => '~', // FULLWIDTH TILDE
+ else => null,
+ };
+}
deps/aro/CodeGen.zig
@@ -0,0 +1,1291 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const Compilation = @import("Compilation.zig");
+const Interner = @import("Interner.zig");
+const Ir = @import("Ir.zig");
+const Builder = Ir.Builder;
+const StringId = @import("StringInterner.zig").StringId;
+const Tree = @import("Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Value = @import("Value.zig");
+
+const CodeGen = @This();
+
+const WipSwitch = struct {
+ cases: Cases = .{},
+ default: ?Ir.Ref = null,
+ size: u64,
+
+ const Cases = std.MultiArrayList(struct {
+ val: Interner.Ref,
+ label: Ir.Ref,
+ });
+};
+
+const Symbol = struct {
+ name: StringId,
+ val: Ir.Ref,
+};
+
+const Error = Compilation.Error;
+
+tree: Tree,
+comp: *Compilation,
+builder: Builder,
+node_tag: []const Tree.Tag,
+node_data: []const Tree.Node.Data,
+node_ty: []const Type,
+wip_switch: *WipSwitch = undefined,
+symbols: std.ArrayListUnmanaged(Symbol) = .{},
+ret_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
+phi_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
+record_elem_buf: std.ArrayListUnmanaged(Interner.Ref) = .{},
+cond_dummy_ty: ?Interner.Ref = null,
+bool_invert: bool = false,
+bool_end_label: Ir.Ref = .none,
+cond_dummy_ref: Ir.Ref = undefined,
+continue_label: Ir.Ref = undefined,
+break_label: Ir.Ref = undefined,
+return_label: Ir.Ref = undefined,
+
+pub fn generateTree(comp: *Compilation, tree: Tree) Compilation.Error!void {
+ var c = CodeGen{
+ .builder = .{
+ .gpa = comp.gpa,
+ .arena = std.heap.ArenaAllocator.init(comp.gpa),
+ },
+ .tree = tree,
+ .comp = comp,
+ .node_tag = tree.nodes.items(.tag),
+ .node_data = tree.nodes.items(.data),
+ .node_ty = tree.nodes.items(.ty),
+ };
+ defer c.symbols.deinit(c.comp.gpa);
+ defer c.ret_nodes.deinit(c.comp.gpa);
+ defer c.phi_nodes.deinit(c.comp.gpa);
+ defer c.record_elem_buf.deinit(c.comp.gpa);
+ defer c.builder.deinit();
+
+ const node_tags = tree.nodes.items(.tag);
+ for (tree.root_decls) |decl| {
+ c.builder.arena.deinit();
+ c.builder.arena = std.heap.ArenaAllocator.init(comp.gpa);
+
+ switch (node_tags[@intFromEnum(decl)]) {
+ .static_assert,
+ .typedef,
+ .struct_decl_two,
+ .union_decl_two,
+ .enum_decl_two,
+ .struct_decl,
+ .union_decl,
+ .enum_decl,
+ => {},
+
+ .fn_proto,
+ .static_fn_proto,
+ .inline_fn_proto,
+ .inline_static_fn_proto,
+ .extern_var,
+ .threadlocal_extern_var,
+ => {},
+
+ .fn_def,
+ .static_fn_def,
+ .inline_fn_def,
+ .inline_static_fn_def,
+ => c.genFn(decl) catch |err| switch (err) {
+ error.FatalError => return error.FatalError,
+ error.OutOfMemory => return error.OutOfMemory,
+ },
+
+ .@"var",
+ .static_var,
+ .threadlocal_var,
+ .threadlocal_static_var,
+ => c.genVar(decl) catch |err| switch (err) {
+ error.FatalError => return error.FatalError,
+ error.OutOfMemory => return error.OutOfMemory,
+ },
+ else => unreachable,
+ }
+ }
+}
+
+fn genType(c: *CodeGen, base_ty: Type) !Interner.Ref {
+ var key: Interner.Key = undefined;
+ const ty = base_ty.canonicalize(.standard);
+ switch (ty.specifier) {
+ .void => return .void,
+ .bool => return .i1,
+ .@"struct" => {
+ key = .{
+ .record = .{
+ .user_ptr = ty.data.record,
+ .elements = undefined, // Not needed for hash lookup.
+ },
+ };
+ if (c.builder.pool.has(key)) |some| return some;
+ const elem_buf_top = c.record_elem_buf.items.len;
+ defer c.record_elem_buf.items.len = elem_buf_top;
+
+ for (ty.data.record.fields) |field| {
+ if (!field.isRegularField()) {
+ return c.comp.diag.fatalNoSrc("TODO lower struct bitfields", .{});
+ }
+ // TODO handle padding bits
+ const field_ref = try c.genType(field.ty);
+ try c.record_elem_buf.append(c.builder.gpa, field_ref);
+ }
+
+ key.record.elements = try c.builder.arena.allocator().dupe(Interner.Ref, c.record_elem_buf.items[elem_buf_top..]);
+ return c.builder.pool.put(c.builder.gpa, key);
+ },
+ .@"union" => {
+ return c.comp.diag.fatalNoSrc("TODO lower union types", .{});
+ },
+ else => {},
+ }
+ if (ty.isPtr()) return .ptr;
+ if (ty.isFunc()) return .func;
+ if (!ty.isReal()) return c.comp.diag.fatalNoSrc("TODO lower complex types", .{});
+ if (ty.isInt()) {
+ const bits = ty.bitSizeof(c.comp).?;
+ key = .{ .int = @intCast(bits) };
+ } else if (ty.isFloat()) {
+ const bits = ty.bitSizeof(c.comp).?;
+ key = .{ .float = @intCast(bits) };
+ } else if (ty.isArray()) {
+ const elem = try c.genType(ty.elemType());
+ key = .{ .array = .{ .child = elem, .len = ty.arrayLen().? } };
+ } else if (ty.specifier == .vector) {
+ const elem = try c.genType(ty.elemType());
+ key = .{ .vector = .{ .child = elem, .len = @intCast(ty.data.array.len) } };
+ } else if (ty.is(.nullptr_t)) {
+ return c.comp.diag.fatalNoSrc("TODO lower nullptr_t", .{});
+ }
+ return c.builder.pool.put(c.builder.gpa, key);
+}
+
+fn genFn(c: *CodeGen, decl: NodeIndex) Error!void {
+ const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
+ const func_ty = c.node_ty[@intFromEnum(decl)].canonicalize(.standard);
+ c.ret_nodes.items.len = 0;
+
+ try c.builder.startFn();
+
+ for (func_ty.data.func.params) |param| {
+ // TODO handle calling convention here
+ const arg = try c.builder.addArg(try c.genType(param.ty));
+
+ const size: u32 = @intCast(param.ty.sizeof(c.comp).?); // TODO add error in parser
+ const @"align" = param.ty.alignof(c.comp);
+ const alloc = try c.builder.addAlloc(size, @"align");
+ try c.builder.addStore(alloc, arg);
+ try c.symbols.append(c.comp.gpa, .{ .name = param.name, .val = alloc });
+ }
+
+ // Generate body
+ c.return_label = try c.builder.makeLabel("return");
+ try c.genStmt(c.node_data[@intFromEnum(decl)].decl.node);
+
+ // Relocate returns
+ if (c.ret_nodes.items.len == 0) {
+ _ = try c.builder.addInst(.ret, .{ .un = .none }, .noreturn);
+ } else if (c.ret_nodes.items.len == 1) {
+ c.builder.body.items.len -= 1;
+ _ = try c.builder.addInst(.ret, .{ .un = c.ret_nodes.items[0].value }, .noreturn);
+ } else {
+ try c.builder.startBlock(c.return_label);
+ const phi = try c.builder.addPhi(c.ret_nodes.items, try c.genType(func_ty.returnType()));
+ _ = try c.builder.addInst(.ret, .{ .un = phi }, .noreturn);
+ }
+
+ var res = Ir{
+ .pool = c.builder.pool,
+ .instructions = c.builder.instructions,
+ .arena = c.builder.arena.state,
+ .body = c.builder.body,
+ .strings = c.tree.strings,
+ };
+ res.dump(c.builder.gpa, name, c.comp.diag.color, std.io.getStdOut().writer()) catch {};
+}
+
+fn addUn(c: *CodeGen, tag: Ir.Inst.Tag, operand: Ir.Ref, ty: Type) !Ir.Ref {
+ return c.builder.addInst(tag, .{ .un = operand }, try c.genType(ty));
+}
+
+fn addBin(c: *CodeGen, tag: Ir.Inst.Tag, lhs: Ir.Ref, rhs: Ir.Ref, ty: Type) !Ir.Ref {
+ return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, try c.genType(ty));
+}
+
+fn addBranch(c: *CodeGen, cond: Ir.Ref, true_label: Ir.Ref, false_label: Ir.Ref) !void {
+ if (true_label == c.bool_end_label) {
+ if (false_label == c.bool_end_label) {
+ try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = cond });
+ return;
+ }
+ try c.addBoolPhi(!c.bool_invert);
+ }
+ if (false_label == c.bool_end_label) {
+ try c.addBoolPhi(c.bool_invert);
+ }
+ return c.builder.addBranch(cond, true_label, false_label);
+}
+
+fn addBoolPhi(c: *CodeGen, value: bool) !void {
+ const val = try c.builder.addConstant(Value.int(@intFromBool(value)), .i1);
+ try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = val });
+}
+
+fn genStmt(c: *CodeGen, node: NodeIndex) Error!void {
+ _ = try c.genExpr(node);
+}
+
+fn genExpr(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
+ std.debug.assert(node != .none);
+ const ty = c.node_ty[@intFromEnum(node)];
+ if (c.tree.value_map.get(node)) |val| {
+ return c.builder.addConstant(val, try c.genType(ty));
+ }
+ const data = c.node_data[@intFromEnum(node)];
+ switch (c.node_tag[@intFromEnum(node)]) {
+ .enumeration_ref,
+ .bool_literal,
+ .int_literal,
+ .char_literal,
+ .float_literal,
+ .double_literal,
+ .imaginary_literal,
+ .string_literal_expr,
+ .alignof_expr,
+ => unreachable, // These should have an entry in value_map.
+ .fn_def,
+ .static_fn_def,
+ .inline_fn_def,
+ .inline_static_fn_def,
+ .invalid,
+ .threadlocal_var,
+ => unreachable,
+ .static_assert,
+ .fn_proto,
+ .static_fn_proto,
+ .inline_fn_proto,
+ .inline_static_fn_proto,
+ .extern_var,
+ .threadlocal_extern_var,
+ .typedef,
+ .struct_decl_two,
+ .union_decl_two,
+ .enum_decl_two,
+ .struct_decl,
+ .union_decl,
+ .enum_decl,
+ .enum_field_decl,
+ .record_field_decl,
+ .indirect_record_field_decl,
+ .struct_forward_decl,
+ .union_forward_decl,
+ .enum_forward_decl,
+ .null_stmt,
+ => {},
+ .static_var,
+ .implicit_static_var,
+ .threadlocal_static_var,
+ => try c.genVar(node), // TODO
+ .@"var" => {
+ const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
+ const @"align" = ty.alignof(c.comp);
+ const alloc = try c.builder.addAlloc(size, @"align");
+ const name = try c.comp.intern(c.tree.tokSlice(data.decl.name));
+ try c.symbols.append(c.comp.gpa, .{ .name = name, .val = alloc });
+ if (data.decl.node != .none) {
+ try c.genInitializer(alloc, ty, data.decl.node);
+ }
+ },
+ .labeled_stmt => {
+ const label = try c.builder.makeLabel("label");
+ try c.builder.startBlock(label);
+ try c.genStmt(data.decl.node);
+ },
+ .compound_stmt_two => {
+ const old_sym_len = c.symbols.items.len;
+ c.symbols.items.len = old_sym_len;
+
+ if (data.bin.lhs != .none) try c.genStmt(data.bin.lhs);
+ if (data.bin.rhs != .none) try c.genStmt(data.bin.rhs);
+ },
+ .compound_stmt => {
+ const old_sym_len = c.symbols.items.len;
+ c.symbols.items.len = old_sym_len;
+
+ for (c.tree.data[data.range.start..data.range.end]) |stmt| try c.genStmt(stmt);
+ },
+ .if_then_else_stmt => {
+ const then_label = try c.builder.makeLabel("if.then");
+ const else_label = try c.builder.makeLabel("if.else");
+ const end_label = try c.builder.makeLabel("if.end");
+
+ try c.genBoolExpr(data.if3.cond, then_label, else_label);
+
+ try c.builder.startBlock(then_label);
+ try c.genStmt(c.tree.data[data.if3.body]); // then
+ try c.builder.addJump(end_label);
+
+ try c.builder.startBlock(else_label);
+ try c.genStmt(c.tree.data[data.if3.body + 1]); // else
+
+ try c.builder.startBlock(end_label);
+ },
+ .if_then_stmt => {
+ const then_label = try c.builder.makeLabel("if.then");
+ const end_label = try c.builder.makeLabel("if.end");
+
+ try c.genBoolExpr(data.bin.lhs, then_label, end_label);
+
+ try c.builder.startBlock(then_label);
+ try c.genStmt(data.bin.rhs); // then
+ try c.builder.startBlock(end_label);
+ },
+ .switch_stmt => {
+ var wip_switch = WipSwitch{
+ .size = c.node_ty[@intFromEnum(data.bin.lhs)].sizeof(c.comp).?,
+ };
+ defer wip_switch.cases.deinit(c.builder.gpa);
+
+ const old_wip_switch = c.wip_switch;
+ defer c.wip_switch = old_wip_switch;
+ c.wip_switch = &wip_switch;
+
+ const old_break_label = c.break_label;
+ defer c.break_label = old_break_label;
+ const end_ref = try c.builder.makeLabel("switch.end");
+ c.break_label = end_ref;
+
+ const cond = try c.genExpr(data.bin.lhs);
+ const switch_index = c.builder.instructions.len;
+ _ = try c.builder.addInst(.@"switch", undefined, .noreturn);
+
+ try c.genStmt(data.bin.rhs); // body
+
+ const default_ref = wip_switch.default orelse end_ref;
+ try c.builder.startBlock(end_ref);
+
+ const a = c.builder.arena.allocator();
+ const switch_data = try a.create(Ir.Inst.Switch);
+ switch_data.* = .{
+ .target = cond,
+ .cases_len = @intCast(wip_switch.cases.len),
+ .case_vals = (try a.dupe(Interner.Ref, wip_switch.cases.items(.val))).ptr,
+ .case_labels = (try a.dupe(Ir.Ref, wip_switch.cases.items(.label))).ptr,
+ .default = default_ref,
+ };
+ c.builder.instructions.items(.data)[switch_index] = .{ .@"switch" = switch_data };
+ },
+ .case_stmt => {
+ const val = c.tree.value_map.get(data.bin.lhs).?;
+ const label = try c.builder.makeLabel("case");
+ try c.builder.startBlock(label);
+ try c.wip_switch.cases.append(c.builder.gpa, .{
+ .val = try c.builder.pool.put(c.builder.gpa, .{ .value = val }),
+ .label = label,
+ });
+ try c.genStmt(data.bin.rhs);
+ },
+ .default_stmt => {
+ const default = try c.builder.makeLabel("default");
+ try c.builder.startBlock(default);
+ c.wip_switch.default = default;
+ try c.genStmt(data.un);
+ },
+ .while_stmt => {
+ const old_break_label = c.break_label;
+ defer c.break_label = old_break_label;
+
+ const old_continue_label = c.continue_label;
+ defer c.continue_label = old_continue_label;
+
+ const cond_label = try c.builder.makeLabel("while.cond");
+ const then_label = try c.builder.makeLabel("while.then");
+ const end_label = try c.builder.makeLabel("while.end");
+
+ c.continue_label = cond_label;
+ c.break_label = end_label;
+
+ try c.builder.startBlock(cond_label);
+ try c.genBoolExpr(data.bin.lhs, then_label, end_label);
+
+ try c.builder.startBlock(then_label);
+ try c.genStmt(data.bin.rhs);
+ try c.builder.addJump(cond_label);
+ try c.builder.startBlock(end_label);
+ },
+ .do_while_stmt => {
+ const old_break_label = c.break_label;
+ defer c.break_label = old_break_label;
+
+ const old_continue_label = c.continue_label;
+ defer c.continue_label = old_continue_label;
+
+ const then_label = try c.builder.makeLabel("do.then");
+ const cond_label = try c.builder.makeLabel("do.cond");
+ const end_label = try c.builder.makeLabel("do.end");
+
+ c.continue_label = cond_label;
+ c.break_label = end_label;
+
+ try c.builder.startBlock(then_label);
+ try c.genStmt(data.bin.rhs);
+
+ try c.builder.startBlock(cond_label);
+ try c.genBoolExpr(data.bin.lhs, then_label, end_label);
+
+ try c.builder.startBlock(end_label);
+ },
+ .for_decl_stmt => {
+ const old_break_label = c.break_label;
+ defer c.break_label = old_break_label;
+
+ const old_continue_label = c.continue_label;
+ defer c.continue_label = old_continue_label;
+
+ const for_decl = data.forDecl(c.tree);
+ for (for_decl.decls) |decl| try c.genStmt(decl);
+
+ const then_label = try c.builder.makeLabel("for.then");
+ var cond_label = then_label;
+ const cont_label = try c.builder.makeLabel("for.cont");
+ const end_label = try c.builder.makeLabel("for.end");
+
+ c.continue_label = cont_label;
+ c.break_label = end_label;
+
+ if (for_decl.cond != .none) {
+ cond_label = try c.builder.makeLabel("for.cond");
+ try c.builder.startBlock(cond_label);
+ try c.genBoolExpr(for_decl.cond, then_label, end_label);
+ }
+ try c.builder.startBlock(then_label);
+ try c.genStmt(for_decl.body);
+ if (for_decl.incr != .none) {
+ _ = try c.genExpr(for_decl.incr);
+ }
+ try c.builder.addJump(cond_label);
+ try c.builder.startBlock(end_label);
+ },
+ .forever_stmt => {
+ const old_break_label = c.break_label;
+ defer c.break_label = old_break_label;
+
+ const old_continue_label = c.continue_label;
+ defer c.continue_label = old_continue_label;
+
+ const then_label = try c.builder.makeLabel("for.then");
+ const end_label = try c.builder.makeLabel("for.end");
+
+ c.continue_label = then_label;
+ c.break_label = end_label;
+
+ try c.builder.startBlock(then_label);
+ try c.genStmt(data.un);
+ try c.builder.startBlock(end_label);
+ },
+ .for_stmt => {
+ const old_break_label = c.break_label;
+ defer c.break_label = old_break_label;
+
+ const old_continue_label = c.continue_label;
+ defer c.continue_label = old_continue_label;
+
+ const for_stmt = data.forStmt(c.tree);
+ if (for_stmt.init != .none) _ = try c.genExpr(for_stmt.init);
+
+ const then_label = try c.builder.makeLabel("for.then");
+ var cond_label = then_label;
+ const cont_label = try c.builder.makeLabel("for.cont");
+ const end_label = try c.builder.makeLabel("for.end");
+
+ c.continue_label = cont_label;
+ c.break_label = end_label;
+
+ if (for_stmt.cond != .none) {
+ cond_label = try c.builder.makeLabel("for.cond");
+ try c.builder.startBlock(cond_label);
+ try c.genBoolExpr(for_stmt.cond, then_label, end_label);
+ }
+ try c.builder.startBlock(then_label);
+ try c.genStmt(for_stmt.body);
+ if (for_stmt.incr != .none) {
+ _ = try c.genExpr(for_stmt.incr);
+ }
+ try c.builder.addJump(cond_label);
+ try c.builder.startBlock(end_label);
+ },
+ .continue_stmt => try c.builder.addJump(c.continue_label),
+ .break_stmt => try c.builder.addJump(c.break_label),
+ .return_stmt => {
+ if (data.un != .none) {
+ const operand = try c.genExpr(data.un);
+ try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
+ }
+ try c.builder.addJump(c.return_label);
+ },
+ .implicit_return => {
+ if (data.return_zero) {
+ const operand = try c.builder.addConstant(Value.int(0), try c.genType(ty));
+ try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
+ }
+ // No need to emit a jump since implicit_return is always the last instruction.
+ },
+ .case_range_stmt,
+ .goto_stmt,
+ .computed_goto_stmt,
+ .nullptr_literal,
+ => return c.comp.diag.fatalNoSrc("TODO CodeGen.genStmt {}\n", .{c.node_tag[@intFromEnum(node)]}),
+ .comma_expr => {
+ _ = try c.genExpr(data.bin.lhs);
+ return c.genExpr(data.bin.rhs);
+ },
+ .assign_expr => {
+ const rhs = try c.genExpr(data.bin.rhs);
+ const lhs = try c.genLval(data.bin.lhs);
+ try c.builder.addStore(lhs, rhs);
+ return rhs;
+ },
+ .mul_assign_expr => return c.genCompoundAssign(node, .mul),
+ .div_assign_expr => return c.genCompoundAssign(node, .div),
+ .mod_assign_expr => return c.genCompoundAssign(node, .mod),
+ .add_assign_expr => return c.genCompoundAssign(node, .add),
+ .sub_assign_expr => return c.genCompoundAssign(node, .sub),
+ .shl_assign_expr => return c.genCompoundAssign(node, .bit_shl),
+ .shr_assign_expr => return c.genCompoundAssign(node, .bit_shr),
+ .bit_and_assign_expr => return c.genCompoundAssign(node, .bit_and),
+ .bit_xor_assign_expr => return c.genCompoundAssign(node, .bit_xor),
+ .bit_or_assign_expr => return c.genCompoundAssign(node, .bit_or),
+ .bit_or_expr => return c.genBinOp(node, .bit_or),
+ .bit_xor_expr => return c.genBinOp(node, .bit_xor),
+ .bit_and_expr => return c.genBinOp(node, .bit_and),
+ .equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_eq);
+ return c.addUn(.zext, cmp, ty);
+ },
+ .not_equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_ne);
+ return c.addUn(.zext, cmp, ty);
+ },
+ .less_than_expr => {
+ const cmp = try c.genComparison(node, .cmp_lt);
+ return c.addUn(.zext, cmp, ty);
+ },
+ .less_than_equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_lte);
+ return c.addUn(.zext, cmp, ty);
+ },
+ .greater_than_expr => {
+ const cmp = try c.genComparison(node, .cmp_gt);
+ return c.addUn(.zext, cmp, ty);
+ },
+ .greater_than_equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_gte);
+ return c.addUn(.zext, cmp, ty);
+ },
+ .shl_expr => return c.genBinOp(node, .bit_shl),
+ .shr_expr => return c.genBinOp(node, .bit_shr),
+ .add_expr => {
+ if (ty.isPtr()) {
+ const lhs_ty = c.node_ty[@intFromEnum(data.bin.lhs)];
+ if (lhs_ty.isPtr()) {
+ const ptr = try c.genExpr(data.bin.lhs);
+ const offset = try c.genExpr(data.bin.rhs);
+ const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
+ return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
+ } else {
+ const offset = try c.genExpr(data.bin.lhs);
+ const ptr = try c.genExpr(data.bin.rhs);
+ const offset_ty = lhs_ty;
+ return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
+ }
+ }
+ return c.genBinOp(node, .add);
+ },
+ .sub_expr => {
+ if (ty.isPtr()) {
+ const ptr = try c.genExpr(data.bin.lhs);
+ const offset = try c.genExpr(data.bin.rhs);
+ const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
+ return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
+ }
+ return c.genBinOp(node, .sub);
+ },
+ .mul_expr => return c.genBinOp(node, .mul),
+ .div_expr => return c.genBinOp(node, .div),
+ .mod_expr => return c.genBinOp(node, .mod),
+ .addr_of_expr => return try c.genLval(data.un),
+ .deref_expr => {
+ const un_data = c.node_data[@intFromEnum(data.un)];
+ if (c.node_tag[@intFromEnum(data.un)] == .implicit_cast and un_data.cast.kind == .function_to_pointer) {
+ return c.genExpr(data.un);
+ }
+ const operand = try c.genLval(data.un);
+ return c.addUn(.load, operand, ty);
+ },
+ .plus_expr => return c.genExpr(data.un),
+ .negate_expr => {
+ const zero = try c.builder.addConstant(Value.int(0), try c.genType(ty));
+ const operand = try c.genExpr(data.un);
+ return c.addBin(.sub, zero, operand, ty);
+ },
+ .bit_not_expr => {
+ const operand = try c.genExpr(data.un);
+ return c.addUn(.bit_not, operand, ty);
+ },
+ .bool_not_expr => {
+ const zero = try c.builder.addConstant(Value.int(0), try c.genType(ty));
+ const operand = try c.genExpr(data.un);
+ return c.addBin(.cmp_ne, zero, operand, ty);
+ },
+ .pre_inc_expr => {
+ const operand = try c.genLval(data.un);
+ const val = try c.addUn(.load, operand, ty);
+ const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+ const plus_one = try c.addBin(.add, val, one, ty);
+ try c.builder.addStore(operand, plus_one);
+ return plus_one;
+ },
+ .pre_dec_expr => {
+ const operand = try c.genLval(data.un);
+ const val = try c.addUn(.load, operand, ty);
+ const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+ const plus_one = try c.addBin(.sub, val, one, ty);
+ try c.builder.addStore(operand, plus_one);
+ return plus_one;
+ },
+ .post_inc_expr => {
+ const operand = try c.genLval(data.un);
+ const val = try c.addUn(.load, operand, ty);
+ const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+ const plus_one = try c.addBin(.add, val, one, ty);
+ try c.builder.addStore(operand, plus_one);
+ return val;
+ },
+ .post_dec_expr => {
+ const operand = try c.genLval(data.un);
+ const val = try c.addUn(.load, operand, ty);
+ const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+ const plus_one = try c.addBin(.sub, val, one, ty);
+ try c.builder.addStore(operand, plus_one);
+ return val;
+ },
+ .paren_expr => return c.genExpr(data.un),
+ .decl_ref_expr => unreachable, // Lval expression.
+ .explicit_cast, .implicit_cast => switch (data.cast.kind) {
+ .no_op => return c.genExpr(data.cast.operand),
+ .to_void => {
+ _ = try c.genExpr(data.cast.operand);
+ return .none;
+ },
+ .lval_to_rval => {
+ const operand = try c.genLval(data.cast.operand);
+ return c.addUn(.load, operand, ty);
+ },
+ .function_to_pointer, .array_to_pointer => {
+ return c.genLval(data.cast.operand);
+ },
+ .int_cast => {
+ const operand = try c.genExpr(data.cast.operand);
+ const src_ty = c.node_ty[@intFromEnum(data.cast.operand)];
+ const src_bits = src_ty.bitSizeof(c.comp).?;
+ const dest_bits = ty.bitSizeof(c.comp).?;
+ if (src_bits == dest_bits) {
+ return operand;
+ } else if (src_bits < dest_bits) {
+ if (src_ty.isUnsignedInt(c.comp))
+ return c.addUn(.zext, operand, ty)
+ else
+ return c.addUn(.sext, operand, ty);
+ } else {
+ return c.addUn(.trunc, operand, ty);
+ }
+ },
+ .bool_to_int => {
+ const operand = try c.genExpr(data.cast.operand);
+ return c.addUn(.zext, operand, ty);
+ },
+ .pointer_to_bool, .int_to_bool, .float_to_bool => {
+ const lhs = try c.genExpr(data.cast.operand);
+ const rhs = try c.builder.addConstant(Value.int(0), try c.genType(c.node_ty[@intFromEnum(node)]));
+ return c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
+ },
+ .bitcast,
+ .pointer_to_int,
+ .bool_to_float,
+ .bool_to_pointer,
+ .int_to_float,
+ .complex_int_to_complex_float,
+ .int_to_pointer,
+ .float_to_int,
+ .complex_float_to_complex_int,
+ .complex_int_cast,
+ .complex_int_to_real,
+ .real_to_complex_int,
+ .float_cast,
+ .complex_float_cast,
+ .complex_float_to_real,
+ .real_to_complex_float,
+ .null_to_pointer,
+ .union_cast,
+ .vector_splat,
+ => return c.comp.diag.fatalNoSrc("TODO CodeGen gen CastKind {}\n", .{data.cast.kind}),
+ },
+ .binary_cond_expr => {
+ if (c.tree.value_map.get(data.if3.cond)) |cond| {
+ if (cond.getBool()) {
+ c.cond_dummy_ref = try c.genExpr(data.if3.cond);
+ return c.genExpr(c.tree.data[data.if3.body]); // then
+ } else {
+ return c.genExpr(c.tree.data[data.if3.body + 1]); // else
+ }
+ }
+
+ const then_label = try c.builder.makeLabel("ternary.then");
+ const else_label = try c.builder.makeLabel("ternary.else");
+ const end_label = try c.builder.makeLabel("ternary.end");
+ const cond_ty = c.node_ty[@intFromEnum(data.if3.cond)];
+ {
+ const old_cond_dummy_ty = c.cond_dummy_ty;
+ defer c.cond_dummy_ty = old_cond_dummy_ty;
+ c.cond_dummy_ty = try c.genType(cond_ty);
+
+ try c.genBoolExpr(data.if3.cond, then_label, else_label);
+ }
+
+ try c.builder.startBlock(then_label);
+ if (c.builder.instructions.items(.ty)[@intFromEnum(c.cond_dummy_ref)] == .i1) {
+ c.cond_dummy_ref = try c.addUn(.zext, c.cond_dummy_ref, cond_ty);
+ }
+ const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
+ try c.builder.addJump(end_label);
+ const then_exit = c.builder.current_label;
+
+ try c.builder.startBlock(else_label);
+ const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
+ const else_exit = c.builder.current_label;
+
+ try c.builder.startBlock(end_label);
+
+ var phi_buf: [2]Ir.Inst.Phi.Input = .{
+ .{ .value = then_val, .label = then_exit },
+ .{ .value = else_val, .label = else_exit },
+ };
+ return c.builder.addPhi(&phi_buf, try c.genType(ty));
+ },
+ .cond_dummy_expr => return c.cond_dummy_ref,
+ .cond_expr => {
+ if (c.tree.value_map.get(data.if3.cond)) |cond| {
+ if (cond.getBool()) {
+ return c.genExpr(c.tree.data[data.if3.body]); // then
+ } else {
+ return c.genExpr(c.tree.data[data.if3.body + 1]); // else
+ }
+ }
+
+ const then_label = try c.builder.makeLabel("ternary.then");
+ const else_label = try c.builder.makeLabel("ternary.else");
+ const end_label = try c.builder.makeLabel("ternary.end");
+
+ try c.genBoolExpr(data.if3.cond, then_label, else_label);
+
+ try c.builder.startBlock(then_label);
+ const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
+ try c.builder.addJump(end_label);
+ const then_exit = c.builder.current_label;
+
+ try c.builder.startBlock(else_label);
+ const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
+ const else_exit = c.builder.current_label;
+
+ try c.builder.startBlock(end_label);
+
+ var phi_buf: [2]Ir.Inst.Phi.Input = .{
+ .{ .value = then_val, .label = then_exit },
+ .{ .value = else_val, .label = else_exit },
+ };
+ return c.builder.addPhi(&phi_buf, try c.genType(ty));
+ },
+ .call_expr_one => if (data.bin.rhs == .none) {
+ return c.genCall(data.bin.lhs, &.{}, ty);
+ } else {
+ return c.genCall(data.bin.lhs, &.{data.bin.rhs}, ty);
+ },
+ .call_expr => {
+ return c.genCall(c.tree.data[data.range.start], c.tree.data[data.range.start + 1 .. data.range.end], ty);
+ },
+ .bool_or_expr => {
+ if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+ const cond = lhs.getBool();
+ if (!cond) {
+ return c.builder.addConstant(Value.int(1), try c.genType(ty));
+ }
+ return c.genExpr(data.bin.rhs);
+ }
+
+ const false_label = try c.builder.makeLabel("bool_false");
+ const exit_label = try c.builder.makeLabel("bool_exit");
+
+ const old_bool_end_label = c.bool_end_label;
+ defer c.bool_end_label = old_bool_end_label;
+ c.bool_end_label = exit_label;
+
+ const phi_nodes_top = c.phi_nodes.items.len;
+ defer c.phi_nodes.items.len = phi_nodes_top;
+
+ try c.genBoolExpr(data.bin.lhs, exit_label, false_label);
+
+ try c.builder.startBlock(false_label);
+ try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
+
+ try c.builder.startBlock(exit_label);
+
+ const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
+ return c.addUn(.zext, phi, ty);
+ },
+ .bool_and_expr => {
+ if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+ const cond = lhs.getBool();
+ if (!cond) {
+ return c.builder.addConstant(Value.int(0), try c.genType(ty));
+ }
+ return c.genExpr(data.bin.rhs);
+ }
+
+ const true_label = try c.builder.makeLabel("bool_true");
+ const exit_label = try c.builder.makeLabel("bool_exit");
+
+ const old_bool_end_label = c.bool_end_label;
+ defer c.bool_end_label = old_bool_end_label;
+ c.bool_end_label = exit_label;
+
+ const phi_nodes_top = c.phi_nodes.items.len;
+ defer c.phi_nodes.items.len = phi_nodes_top;
+
+ try c.genBoolExpr(data.bin.lhs, true_label, exit_label);
+
+ try c.builder.startBlock(true_label);
+ try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
+
+ try c.builder.startBlock(exit_label);
+
+ const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
+ return c.addUn(.zext, phi, ty);
+ },
+ .builtin_choose_expr => {
+ const cond = c.tree.value_map.get(data.if3.cond).?;
+ if (cond.getBool()) {
+ return c.genExpr(c.tree.data[data.if3.body]);
+ } else {
+ return c.genExpr(c.tree.data[data.if3.body + 1]);
+ }
+ },
+ .generic_expr_one => {
+ const index = @intFromEnum(data.bin.rhs);
+ switch (c.node_tag[index]) {
+ .generic_association_expr, .generic_default_expr => {
+ return c.genExpr(c.node_data[index].un);
+ },
+ else => unreachable,
+ }
+ },
+ .generic_expr => {
+ const index = @intFromEnum(c.tree.data[data.range.start + 1]);
+ switch (c.node_tag[index]) {
+ .generic_association_expr, .generic_default_expr => {
+ return c.genExpr(c.node_data[index].un);
+ },
+ else => unreachable,
+ }
+ },
+ .generic_association_expr, .generic_default_expr => unreachable,
+ .stmt_expr => switch (c.node_tag[@intFromEnum(data.un)]) {
+ .compound_stmt_two => {
+ const old_sym_len = c.symbols.items.len;
+ c.symbols.items.len = old_sym_len;
+
+ const stmt_data = c.node_data[@intFromEnum(data.un)];
+ if (stmt_data.bin.rhs == .none) return c.genExpr(stmt_data.bin.lhs);
+ try c.genStmt(stmt_data.bin.lhs);
+ return c.genExpr(stmt_data.bin.rhs);
+ },
+ .compound_stmt => {
+ const old_sym_len = c.symbols.items.len;
+ c.symbols.items.len = old_sym_len;
+
+ const stmt_data = c.node_data[@intFromEnum(data.un)];
+ for (c.tree.data[stmt_data.range.start .. stmt_data.range.end - 1]) |stmt| try c.genStmt(stmt);
+ return c.genExpr(c.tree.data[stmt_data.range.end]);
+ },
+ else => unreachable,
+ },
+ .builtin_call_expr_one => {
+ const name = c.tree.tokSlice(data.decl.name);
+ const builtin = c.comp.builtins.lookup(name).builtin;
+ if (data.decl.node == .none) {
+ return c.genBuiltinCall(builtin, &.{}, ty);
+ } else {
+ return c.genBuiltinCall(builtin, &.{data.decl.node}, ty);
+ }
+ },
+ .builtin_call_expr => {
+ const name_node_idx = c.tree.data[data.range.start];
+ const name = c.tree.tokSlice(@intFromEnum(name_node_idx));
+ const builtin = c.comp.builtins.lookup(name).builtin;
+ return c.genBuiltinCall(builtin, c.tree.data[data.range.start + 1 .. data.range.end], ty);
+ },
+ .addr_of_label,
+ .imag_expr,
+ .real_expr,
+ .sizeof_expr,
+ .special_builtin_call_one,
+ => return c.comp.diag.fatalNoSrc("TODO CodeGen.genExpr {}\n", .{c.node_tag[@intFromEnum(node)]}),
+ else => unreachable, // Not an expression.
+ }
+ return .none;
+}
+
+fn genLval(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
+ std.debug.assert(node != .none);
+ assert(Tree.isLval(c.tree.nodes, c.tree.data, c.tree.value_map, node));
+ const data = c.node_data[@intFromEnum(node)];
+ switch (c.node_tag[@intFromEnum(node)]) {
+ .string_literal_expr => {
+ const val = c.tree.value_map.get(node).?;
+ return c.builder.addConstant(val, .ptr);
+ },
+ .paren_expr => return c.genLval(data.un),
+ .decl_ref_expr => {
+ const slice = c.tree.tokSlice(data.decl_ref);
+ const name = try c.comp.intern(slice);
+ var i = c.symbols.items.len;
+ while (i > 0) {
+ i -= 1;
+ if (c.symbols.items[i].name == name) {
+ return c.symbols.items[i].val;
+ }
+ }
+
+ const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
+ const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
+ try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
+ return ref;
+ },
+ .deref_expr => return c.genExpr(data.un),
+ .compound_literal_expr => {
+ const ty = c.node_ty[@intFromEnum(node)];
+ const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
+ const @"align" = ty.alignof(c.comp);
+ const alloc = try c.builder.addAlloc(size, @"align");
+ try c.genInitializer(alloc, ty, data.un);
+ return alloc;
+ },
+ .builtin_choose_expr => {
+ const cond = c.tree.value_map.get(data.if3.cond).?;
+ if (cond.getBool()) {
+ return c.genLval(c.tree.data[data.if3.body]);
+ } else {
+ return c.genLval(c.tree.data[data.if3.body + 1]);
+ }
+ },
+ .member_access_expr,
+ .member_access_ptr_expr,
+ .array_access_expr,
+ => return c.comp.diag.fatalNoSrc("TODO CodeGen.genLval {}\n", .{c.node_tag[@intFromEnum(node)]}),
+ else => unreachable, // Not an lval expression.
+ }
+}
+
+fn genBoolExpr(c: *CodeGen, base: NodeIndex, true_label: Ir.Ref, false_label: Ir.Ref) Error!void {
+ var node = base;
+ while (true) switch (c.node_tag[@intFromEnum(node)]) {
+ .paren_expr => {
+ node = c.node_data[@intFromEnum(node)].un;
+ },
+ else => break,
+ };
+
+ const data = c.node_data[@intFromEnum(node)];
+ switch (c.node_tag[@intFromEnum(node)]) {
+ .bool_or_expr => {
+ if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+ const cond = lhs.getBool();
+ if (cond) {
+ if (true_label == c.bool_end_label) {
+ return c.addBoolPhi(!c.bool_invert);
+ }
+ return c.builder.addJump(true_label);
+ }
+ return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+ }
+
+ const new_false_label = try c.builder.makeLabel("bool_false");
+ try c.genBoolExpr(data.bin.lhs, true_label, new_false_label);
+ try c.builder.startBlock(new_false_label);
+
+ if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+ return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+ },
+ .bool_and_expr => {
+ if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+ const cond = lhs.getBool();
+ if (!cond) {
+ if (false_label == c.bool_end_label) {
+ return c.addBoolPhi(c.bool_invert);
+ }
+ return c.builder.addJump(false_label);
+ }
+ return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+ }
+
+ const new_true_label = try c.builder.makeLabel("bool_true");
+ try c.genBoolExpr(data.bin.lhs, new_true_label, false_label);
+ try c.builder.startBlock(new_true_label);
+
+ if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+ return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+ },
+ .bool_not_expr => {
+ c.bool_invert = !c.bool_invert;
+ defer c.bool_invert = !c.bool_invert;
+
+ if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(0), ty);
+ return c.genBoolExpr(data.un, false_label, true_label);
+ },
+ .equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_eq);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+ return c.addBranch(cmp, true_label, false_label);
+ },
+ .not_equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_ne);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+ return c.addBranch(cmp, true_label, false_label);
+ },
+ .less_than_expr => {
+ const cmp = try c.genComparison(node, .cmp_lt);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+ return c.addBranch(cmp, true_label, false_label);
+ },
+ .less_than_equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_lte);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+ return c.addBranch(cmp, true_label, false_label);
+ },
+ .greater_than_expr => {
+ const cmp = try c.genComparison(node, .cmp_gt);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+ return c.addBranch(cmp, true_label, false_label);
+ },
+ .greater_than_equal_expr => {
+ const cmp = try c.genComparison(node, .cmp_gte);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+ return c.addBranch(cmp, true_label, false_label);
+ },
+ .explicit_cast, .implicit_cast => switch (data.cast.kind) {
+ .bool_to_int => {
+ const operand = try c.genExpr(data.cast.operand);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = operand;
+ return c.addBranch(operand, true_label, false_label);
+ },
+ else => {},
+ },
+ .binary_cond_expr => {
+ if (c.tree.value_map.get(data.if3.cond)) |cond| {
+ if (cond.getBool()) {
+ return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
+ } else {
+ return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+ }
+ }
+
+ const new_false_label = try c.builder.makeLabel("ternary.else");
+ try c.genBoolExpr(data.if3.cond, true_label, new_false_label);
+
+ try c.builder.startBlock(new_false_label);
+ if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+ return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+ },
+ .cond_expr => {
+ if (c.tree.value_map.get(data.if3.cond)) |cond| {
+ if (cond.getBool()) {
+ return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
+ } else {
+ return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+ }
+ }
+
+ const new_true_label = try c.builder.makeLabel("ternary.then");
+ const new_false_label = try c.builder.makeLabel("ternary.else");
+ try c.genBoolExpr(data.if3.cond, new_true_label, new_false_label);
+
+ try c.builder.startBlock(new_true_label);
+ try c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
+ try c.builder.startBlock(new_false_label);
+ if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+ return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+ },
+ else => {},
+ }
+
+ if (c.tree.value_map.get(node)) |value| {
+ if (value.getBool()) {
+ if (true_label == c.bool_end_label) {
+ return c.addBoolPhi(!c.bool_invert);
+ }
+ return c.builder.addJump(true_label);
+ } else {
+ if (false_label == c.bool_end_label) {
+ return c.addBoolPhi(c.bool_invert);
+ }
+ return c.builder.addJump(false_label);
+ }
+ }
+
+ // Assume int operand.
+ const lhs = try c.genExpr(node);
+ const rhs = try c.builder.addConstant(Value.int(0), try c.genType(c.node_ty[@intFromEnum(node)]));
+ const cmp = try c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
+ if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+ try c.addBranch(cmp, true_label, false_label);
+}
+
+fn genBuiltinCall(c: *CodeGen, builtin: BuiltinFunction, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
+ _ = arg_nodes;
+ _ = ty;
+ return c.comp.diag.fatalNoSrc("TODO CodeGen.genBuiltinCall {s}\n", .{@tagName(builtin.tag)});
+}
+
+fn genCall(c: *CodeGen, fn_node: NodeIndex, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
+ // Detect direct calls.
+ const fn_ref = blk: {
+ const data = c.node_data[@intFromEnum(fn_node)];
+ if (c.node_tag[@intFromEnum(fn_node)] != .implicit_cast or data.cast.kind != .function_to_pointer) {
+ break :blk try c.genExpr(fn_node);
+ }
+
+ var cur = @intFromEnum(data.cast.operand);
+ while (true) switch (c.node_tag[cur]) {
+ .paren_expr, .addr_of_expr, .deref_expr => {
+ cur = @intFromEnum(c.node_data[cur].un);
+ },
+ .implicit_cast => {
+ const cast = c.node_data[cur].cast;
+ if (cast.kind != .function_to_pointer) {
+ break :blk try c.genExpr(fn_node);
+ }
+ cur = @intFromEnum(cast.operand);
+ },
+ .decl_ref_expr => {
+ const slice = c.tree.tokSlice(c.node_data[cur].decl_ref);
+ const name = try c.comp.intern(slice);
+ var i = c.symbols.items.len;
+ while (i > 0) {
+ i -= 1;
+ if (c.symbols.items[i].name == name) {
+ break :blk try c.genExpr(fn_node);
+ }
+ }
+
+ const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
+ const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
+ try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
+ break :blk ref;
+ },
+ else => break :blk try c.genExpr(fn_node),
+ };
+ };
+
+ const args = try c.builder.arena.allocator().alloc(Ir.Ref, arg_nodes.len);
+ for (arg_nodes, args) |node, *arg| {
+ // TODO handle calling convention here
+ arg.* = try c.genExpr(node);
+ }
+ // TODO handle variadic call
+ const call = try c.builder.arena.allocator().create(Ir.Inst.Call);
+ call.* = .{
+ .func = fn_ref,
+ .args_len = @intCast(args.len),
+ .args_ptr = args.ptr,
+ };
+ return c.builder.addInst(.call, .{ .call = call }, try c.genType(ty));
+}
+
+fn genCompoundAssign(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
+ const bin = c.node_data[@intFromEnum(node)].bin;
+ const ty = c.node_ty[@intFromEnum(node)];
+ const rhs = try c.genExpr(bin.rhs);
+ const lhs = try c.genLval(bin.lhs);
+ const res = try c.addBin(tag, lhs, rhs, ty);
+ try c.builder.addStore(lhs, res);
+ return res;
+}
+
+fn genBinOp(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
+ const bin = c.node_data[@intFromEnum(node)].bin;
+ const ty = c.node_ty[@intFromEnum(node)];
+ const lhs = try c.genExpr(bin.lhs);
+ const rhs = try c.genExpr(bin.rhs);
+ return c.addBin(tag, lhs, rhs, ty);
+}
+
+fn genComparison(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
+ const bin = c.node_data[@intFromEnum(node)].bin;
+ const lhs = try c.genExpr(bin.lhs);
+ const rhs = try c.genExpr(bin.rhs);
+
+ return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
+}
+
+fn genPtrArithmetic(c: *CodeGen, ptr: Ir.Ref, offset: Ir.Ref, offset_ty: Type, ty: Type) Error!Ir.Ref {
+ // TODO consider adding a getelemptr instruction
+ const size = ty.elemType().sizeof(c.comp).?;
+ if (size == 1) {
+ return c.builder.addInst(.add, .{ .bin = .{ .lhs = ptr, .rhs = offset } }, try c.genType(ty));
+ }
+
+ const size_inst = try c.builder.addConstant(Value.int(size), try c.genType(offset_ty));
+ const offset_inst = try c.addBin(.mul, offset, size_inst, offset_ty);
+ return c.addBin(.add, ptr, offset_inst, offset_ty);
+}
+
+fn genInitializer(c: *CodeGen, ptr: Ir.Ref, dest_ty: Type, initializer: NodeIndex) Error!void {
+ std.debug.assert(initializer != .none);
+ switch (c.node_tag[@intFromEnum(initializer)]) {
+ .array_init_expr_two,
+ .array_init_expr,
+ .struct_init_expr_two,
+ .struct_init_expr,
+ .union_init_expr,
+ .array_filler_expr,
+ .default_init_expr,
+ => return c.comp.diag.fatalNoSrc("TODO CodeGen.genInitializer {}\n", .{c.node_tag[@intFromEnum(initializer)]}),
+ .string_literal_expr => {
+ const val = c.tree.value_map.get(initializer).?;
+ const str_ptr = try c.builder.addConstant(val, .ptr);
+ if (dest_ty.isArray()) {
+ return c.comp.diag.fatalNoSrc("TODO memcpy\n", .{});
+ } else {
+ try c.builder.addStore(ptr, str_ptr);
+ }
+ },
+ else => {
+ const res = try c.genExpr(initializer);
+ try c.builder.addStore(ptr, res);
+ },
+ }
+}
+
+fn genVar(c: *CodeGen, decl: NodeIndex) Error!void {
+ _ = decl;
+ return c.comp.diag.fatalNoSrc("TODO CodeGen.genVar\n", .{});
+}
deps/aro/Codegen_legacy.zig
@@ -0,0 +1,108 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Tree = @import("Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const Object = @import("Object.zig");
+const x86_64 = @import("codegen/x86_64.zig");
+
+const Codegen = @This();
+
+comp: *Compilation,
+tree: Tree,
+obj: *Object,
+node_tag: []const Tree.Tag,
+node_data: []const Tree.Node.Data,
+
+pub const Error = Compilation.Error || error{CodegenFailed};
+
+/// Generate tree to an object file.
+/// Caller is responsible for flushing and freeing the returned object.
+pub fn generateTree(comp: *Compilation, tree: Tree) Compilation.Error!*Object {
+ var c = Codegen{
+ .comp = comp,
+ .tree = tree,
+ .obj = try Object.create(comp),
+ .node_tag = tree.nodes.items(.tag),
+ .node_data = tree.nodes.items(.data),
+ };
+ errdefer c.obj.deinit();
+
+ const node_tags = tree.nodes.items(.tag);
+ for (tree.root_decls) |decl| {
+ switch (node_tags[@intFromEnum(decl)]) {
+ // these produce no code
+ .static_assert,
+ .typedef,
+ .struct_decl_two,
+ .union_decl_two,
+ .enum_decl_two,
+ .struct_decl,
+ .union_decl,
+ .enum_decl,
+ .struct_forward_decl,
+ .union_forward_decl,
+ .enum_forward_decl,
+ => {},
+
+ // define symbol
+ .fn_proto,
+ .static_fn_proto,
+ .inline_fn_proto,
+ .inline_static_fn_proto,
+ .extern_var,
+ .threadlocal_extern_var,
+ => {
+ const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
+ _ = try c.obj.declareSymbol(.undefined, name, .Strong, .external, 0, 0);
+ },
+
+ // function definition
+ .fn_def,
+ .static_fn_def,
+ .inline_fn_def,
+ .inline_static_fn_def,
+ => c.genFn(decl) catch |err| switch (err) {
+ error.FatalError => return error.FatalError,
+ error.OutOfMemory => return error.OutOfMemory,
+ error.CodegenFailed => continue,
+ },
+
+ .@"var",
+ .static_var,
+ .threadlocal_var,
+ .threadlocal_static_var,
+ .implicit_static_var,
+ => c.genVar(decl) catch |err| switch (err) {
+ error.FatalError => return error.FatalError,
+ error.OutOfMemory => return error.OutOfMemory,
+ error.CodegenFailed => continue,
+ },
+
+ // TODO
+ .file_scope_asm => {},
+
+ else => unreachable,
+ }
+ }
+
+ return c.obj;
+}
+
+fn genFn(c: *Codegen, decl: NodeIndex) Error!void {
+ const section: Object.Section = .func;
+ const data = try c.obj.getSection(section);
+ const start_len = data.items.len;
+ switch (c.comp.target.cpu.arch) {
+ .x86_64 => try x86_64.genFn(c, decl, data),
+ else => unreachable,
+ }
+ const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
+ _ = try c.obj.declareSymbol(section, name, .Strong, .func, start_len, data.items.len - start_len);
+}
+
+fn genVar(c: *Codegen, decl: NodeIndex) Error!void {
+ switch (c.comp.target.cpu.arch) {
+ .x86_64 => try x86_64.genVar(c, decl),
+ else => unreachable,
+ }
+}
deps/aro/Compilation.zig
@@ -0,0 +1,1491 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const EpochSeconds = std.time.epoch.EpochSeconds;
+const Builtins = @import("Builtins.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const LangOpts = @import("LangOpts.zig");
+const Source = @import("Source.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const Token = Tokenizer.Token;
+const Type = @import("Type.zig");
+const Pragma = @import("Pragma.zig");
+const StringInterner = @import("StringInterner.zig");
+const record_layout = @import("record_layout.zig");
+const target_util = @import("target.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+
+const Compilation = @This();
+
+pub const Error = error{
+ /// A fatal error has ocurred and compilation has stopped.
+ FatalError,
+} || Allocator.Error;
+
+pub const bit_int_max_bits = 128;
+const path_buf_stack_limit = 1024;
+
+/// Environment variables used during compilation / linking.
+pub const Environment = struct {
+ /// Directory to use for temporary files
+ /// TODO: not implemented yet
+ tmpdir: ?[]const u8 = null,
+
+ /// PATH environment variable used to search for programs
+ path: ?[]const u8 = null,
+
+ /// Directories to try when searching for subprograms.
+ /// TODO: not implemented yet
+ compiler_path: ?[]const u8 = null,
+
+ /// Directories to try when searching for special linker files, if compiling for the native target
+ /// TODO: not implemented yet
+ library_path: ?[]const u8 = null,
+
+ /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
+ /// Used regardless of the language being compiled
+ /// TODO: not implemented yet
+ cpath: ?[]const u8 = null,
+
+ /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
+ /// Used if the language being compiled is C
+ /// TODO: not implemented yet
+ c_include_path: ?[]const u8 = null,
+
+ /// UNIX timestamp to be used instead of the current date and time in the __DATE__ and __TIME__ macros
+ source_date_epoch: ?[]const u8 = null,
+
+ /// Load all of the environment variables using the std.process API. Do not use if using Aro as a shared library on Linux without libc
+ /// See https://github.com/ziglang/zig/issues/4524
+ /// Assumes that `self` has been default-initialized
+ pub fn loadAll(self: *Environment, allocator: std.mem.Allocator) !void {
+ errdefer self.deinit(allocator);
+
+ inline for (@typeInfo(@TypeOf(self.*)).Struct.fields) |field| {
+ std.debug.assert(@field(self, field.name) == null);
+
+ var env_var_buf: [field.name.len]u8 = undefined;
+ const env_var_name = std.ascii.upperString(&env_var_buf, field.name);
+ const val: ?[]const u8 = std.process.getEnvVarOwned(allocator, env_var_name) catch |err| switch (err) {
+ error.OutOfMemory => |e| return e,
+ error.EnvironmentVariableNotFound => null,
+ error.InvalidUtf8 => null,
+ };
+ @field(self, field.name) = val;
+ }
+ }
+
+ /// Use this only if environment slices were allocated with `allocator` (such as via `loadAll`)
+ pub fn deinit(self: *Environment, allocator: std.mem.Allocator) void {
+ inline for (@typeInfo(@TypeOf(self.*)).Struct.fields) |field| {
+ if (@field(self, field.name)) |slice| {
+ allocator.free(slice);
+ }
+ }
+ self.* = undefined;
+ }
+};
+
+gpa: Allocator,
+environment: Environment = .{},
+sources: std.StringArrayHashMap(Source),
+diag: Diagnostics,
+include_dirs: std.ArrayList([]const u8),
+system_include_dirs: std.ArrayList([]const u8),
+target: std.Target = @import("builtin").target,
+pragma_handlers: std.StringArrayHashMap(*Pragma),
+langopts: LangOpts = .{},
+generated_buf: std.ArrayList(u8),
+builtins: Builtins = .{},
+types: struct {
+ wchar: Type = undefined,
+ ptrdiff: Type = undefined,
+ size: Type = undefined,
+ va_list: Type = undefined,
+ pid_t: Type = undefined,
+ ns_constant_string: struct {
+ ty: Type = undefined,
+ record: Type.Record = undefined,
+ fields: [4]Type.Record.Field = undefined,
+ int_ty: Type = .{ .specifier = .int, .qual = .{ .@"const" = true } },
+ char_ty: Type = .{ .specifier = .char, .qual = .{ .@"const" = true } },
+ } = .{},
+ file: Type = .{ .specifier = .invalid },
+ jmp_buf: Type = .{ .specifier = .invalid },
+ sigjmp_buf: Type = .{ .specifier = .invalid },
+ ucontext_t: Type = .{ .specifier = .invalid },
+ intmax: Type = .{ .specifier = .invalid },
+ intptr: Type = .{ .specifier = .invalid },
+ int16: Type = .{ .specifier = .invalid },
+ int64: Type = .{ .specifier = .invalid },
+} = .{},
+/// Mapping from Source.Id to byte offset of first non-utf8 byte
+invalid_utf8_locs: std.AutoHashMapUnmanaged(Source.Id, u32) = .{},
+string_interner: StringInterner = .{},
+
+pub fn init(gpa: Allocator) Compilation {
+ return .{
+ .gpa = gpa,
+ .sources = std.StringArrayHashMap(Source).init(gpa),
+ .diag = Diagnostics.init(gpa),
+ .include_dirs = std.ArrayList([]const u8).init(gpa),
+ .system_include_dirs = std.ArrayList([]const u8).init(gpa),
+ .pragma_handlers = std.StringArrayHashMap(*Pragma).init(gpa),
+ .generated_buf = std.ArrayList(u8).init(gpa),
+ };
+}
+
+pub fn deinit(comp: *Compilation) void {
+ for (comp.pragma_handlers.values()) |pragma| {
+ pragma.deinit(pragma, comp);
+ }
+ for (comp.sources.values()) |source| {
+ comp.gpa.free(source.path);
+ comp.gpa.free(source.buf);
+ comp.gpa.free(source.splice_locs);
+ }
+ comp.sources.deinit();
+ comp.diag.deinit();
+ comp.include_dirs.deinit();
+ for (comp.system_include_dirs.items) |path| comp.gpa.free(path);
+ comp.system_include_dirs.deinit();
+ comp.pragma_handlers.deinit();
+ comp.generated_buf.deinit();
+ comp.builtins.deinit(comp.gpa);
+ comp.invalid_utf8_locs.deinit(comp.gpa);
+ comp.string_interner.deinit(comp.gpa);
+}
+
+pub fn intern(comp: *Compilation, str: []const u8) !StringInterner.StringId {
+ return comp.string_interner.intern(comp.gpa, str);
+}
+
+pub fn getSourceEpoch(self: *const Compilation, max: i64) !?i64 {
+ const provided = self.environment.source_date_epoch orelse return null;
+ const parsed = std.fmt.parseInt(i64, provided, 10) catch return error.InvalidEpoch;
+ if (parsed < 0 or parsed > max) return error.InvalidEpoch;
+ return parsed;
+}
+
+/// Dec 31 9999 23:59:59
+const max_timestamp = 253402300799;
+
+fn getTimestamp(comp: *Compilation) !u47 {
+ const provided: ?i64 = comp.getSourceEpoch(max_timestamp) catch blk: {
+ try comp.diag.add(.{
+ .tag = .invalid_source_epoch,
+ .loc = .{ .id = .unused, .byte_offset = 0, .line = 0 },
+ }, &.{});
+ break :blk null;
+ };
+ const timestamp = provided orelse std.time.timestamp();
+ return @intCast(std.math.clamp(timestamp, 0, max_timestamp));
+}
+
+fn generateDateAndTime(w: anytype, timestamp: u47) !void {
+ const epoch_seconds = EpochSeconds{ .secs = timestamp };
+ const epoch_day = epoch_seconds.getEpochDay();
+ const day_seconds = epoch_seconds.getDaySeconds();
+ const year_day = epoch_day.calculateYearDay();
+ const month_day = year_day.calculateMonthDay();
+
+ const month_names = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+ std.debug.assert(std.time.epoch.Month.jan.numeric() == 1);
+
+ const month_name = month_names[month_day.month.numeric() - 1];
+ try w.print("#define __DATE__ \"{s} {d: >2} {d}\"\n", .{
+ month_name,
+ month_day.day_index + 1,
+ year_day.year,
+ });
+ try w.print("#define __TIME__ \"{d:0>2}:{d:0>2}:{d:0>2}\"\n", .{
+ day_seconds.getHoursIntoDay(),
+ day_seconds.getMinutesIntoHour(),
+ day_seconds.getSecondsIntoMinute(),
+ });
+
+ const day_names = [_][]const u8{ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+ // days since Thu Oct 1 1970
+ const day_name = day_names[@intCast((epoch_day.day + 3) % 7)];
+ try w.print("#define __TIMESTAMP__ \"{s} {s} {d: >2} {d:0>2}:{d:0>2}:{d:0>2} {d}\"\n", .{
+ day_name,
+ month_name,
+ month_day.day_index + 1,
+ day_seconds.getHoursIntoDay(),
+ day_seconds.getMinutesIntoHour(),
+ day_seconds.getSecondsIntoMinute(),
+ year_day.year,
+ });
+}
+
+/// Generate builtin macros that will be available to each source file.
+pub fn generateBuiltinMacros(comp: *Compilation) !Source {
+ try comp.generateBuiltinTypes();
+
+ var buf = std.ArrayList(u8).init(comp.gpa);
+ defer buf.deinit();
+ const w = buf.writer();
+
+ // standard macros
+ try w.writeAll(
+ \\#define __VERSION__ "Aro
+ ++ @import("lib.zig").version_str ++ "\"\n" ++
+ \\#define __Aro__
+ \\#define __STDC__ 1
+ \\#define __STDC_HOSTED__ 1
+ \\#define __STDC_NO_ATOMICS__ 1
+ \\#define __STDC_NO_COMPLEX__ 1
+ \\#define __STDC_NO_THREADS__ 1
+ \\#define __STDC_NO_VLA__ 1
+ \\
+ );
+ if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| {
+ try w.print("#define __STDC_VERSION__ {s}\n", .{stdc_version});
+ }
+ const ptr_width = comp.target.ptrBitWidth();
+
+ // os macros
+ switch (comp.target.os.tag) {
+ .linux => try w.writeAll(
+ \\#define linux 1
+ \\#define __linux 1
+ \\#define __linux__ 1
+ \\
+ ),
+ .windows => if (ptr_width == 32) try w.writeAll(
+ \\#define WIN32 1
+ \\#define _WIN32 1
+ \\#define __WIN32 1
+ \\#define __WIN32__ 1
+ \\
+ ) else try w.writeAll(
+ \\#define WIN32 1
+ \\#define WIN64 1
+ \\#define _WIN32 1
+ \\#define _WIN64 1
+ \\#define __WIN32 1
+ \\#define __WIN64 1
+ \\#define __WIN32__ 1
+ \\#define __WIN64__ 1
+ \\
+ ),
+ .freebsd => try w.print("#define __FreeBSD__ {d}\n", .{comp.target.os.version_range.semver.min.major}),
+ .netbsd => try w.writeAll("#define __NetBSD__ 1\n"),
+ .openbsd => try w.writeAll("#define __OpenBSD__ 1\n"),
+ .dragonfly => try w.writeAll("#define __DragonFly__ 1\n"),
+ .solaris => try w.writeAll(
+ \\#define sun 1
+ \\#define __sun 1
+ \\
+ ),
+ .macos => try w.writeAll(
+ \\#define __APPLE__ 1
+ \\#define __MACH__ 1
+ \\
+ ),
+ else => {},
+ }
+
+ // unix and other additional os macros
+ switch (comp.target.os.tag) {
+ .freebsd,
+ .netbsd,
+ .openbsd,
+ .dragonfly,
+ .linux,
+ => try w.writeAll(
+ \\#define unix 1
+ \\#define __unix 1
+ \\#define __unix__ 1
+ \\
+ ),
+ else => {},
+ }
+ if (comp.target.abi == .android) {
+ try w.writeAll("#define __ANDROID__ 1\n");
+ }
+
+ // architecture macros
+ switch (comp.target.cpu.arch) {
+ .x86_64 => try w.writeAll(
+ \\#define __amd64__ 1
+ \\#define __amd64 1
+ \\#define __x86_64 1
+ \\#define __x86_64__ 1
+ \\
+ ),
+ .x86 => try w.writeAll(
+ \\#define i386 1
+ \\#define __i386 1
+ \\#define __i386__ 1
+ \\
+ ),
+ .mips,
+ .mipsel,
+ .mips64,
+ .mips64el,
+ => try w.writeAll(
+ \\#define __mips__ 1
+ \\#define mips 1
+ \\
+ ),
+ .powerpc,
+ .powerpcle,
+ => try w.writeAll(
+ \\#define __powerpc__ 1
+ \\#define __POWERPC__ 1
+ \\#define __ppc__ 1
+ \\#define __PPC__ 1
+ \\#define _ARCH_PPC 1
+ \\
+ ),
+ .powerpc64,
+ .powerpc64le,
+ => try w.writeAll(
+ \\#define __powerpc 1
+ \\#define __powerpc__ 1
+ \\#define __powerpc64__ 1
+ \\#define __POWERPC__ 1
+ \\#define __ppc__ 1
+ \\#define __ppc64__ 1
+ \\#define __PPC__ 1
+ \\#define __PPC64__ 1
+ \\#define _ARCH_PPC 1
+ \\#define _ARCH_PPC64 1
+ \\
+ ),
+ .sparc64 => try w.writeAll(
+ \\#define __sparc__ 1
+ \\#define __sparc 1
+ \\#define __sparc_v9__ 1
+ \\
+ ),
+ .sparc, .sparcel => try w.writeAll(
+ \\#define __sparc__ 1
+ \\#define __sparc 1
+ \\
+ ),
+ .arm, .armeb => try w.writeAll(
+ \\#define __arm__ 1
+ \\#define __arm 1
+ \\
+ ),
+ .thumb, .thumbeb => try w.writeAll(
+ \\#define __arm__ 1
+ \\#define __arm 1
+ \\#define __thumb__ 1
+ \\
+ ),
+ .aarch64, .aarch64_be => try w.writeAll("#define __aarch64__ 1\n"),
+ .msp430 => try w.writeAll(
+ \\#define MSP430 1
+ \\#define __MSP430__ 1
+ \\
+ ),
+ else => {},
+ }
+
+ if (comp.target.os.tag != .windows) switch (ptr_width) {
+ 64 => try w.writeAll(
+ \\#define _LP64 1
+ \\#define __LP64__ 1
+ \\
+ ),
+ 32 => try w.writeAll("#define _ILP32 1\n"),
+ else => {},
+ };
+
+ try w.writeAll(
+ \\#define __ORDER_LITTLE_ENDIAN__ 1234
+ \\#define __ORDER_BIG_ENDIAN__ 4321
+ \\#define __ORDER_PDP_ENDIAN__ 3412
+ \\
+ );
+ if (comp.target.cpu.arch.endian() == .Little) try w.writeAll(
+ \\#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+ \\#define __LITTLE_ENDIAN__ 1
+ \\
+ ) else try w.writeAll(
+ \\#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+ \\#define __BIG_ENDIAN__ 1
+ \\
+ );
+
+ // timestamps
+ const timestamp = try comp.getTimestamp();
+ try generateDateAndTime(w, timestamp);
+
+ // types
+ if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
+ try w.writeAll("#define __CHAR_BIT__ 8\n");
+
+ // int maxs
+ try comp.generateIntWidth(w, "BOOL", .{ .specifier = .bool });
+ try comp.generateIntMaxAndWidth(w, "SCHAR", .{ .specifier = .schar });
+ try comp.generateIntMaxAndWidth(w, "SHRT", .{ .specifier = .short });
+ try comp.generateIntMaxAndWidth(w, "INT", .{ .specifier = .int });
+ try comp.generateIntMaxAndWidth(w, "LONG", .{ .specifier = .long });
+ try comp.generateIntMaxAndWidth(w, "LONG_LONG", .{ .specifier = .long_long });
+ try comp.generateIntMaxAndWidth(w, "WCHAR", comp.types.wchar);
+ // try comp.generateIntMax(w, "WINT", comp.types.wchar);
+ try comp.generateIntMaxAndWidth(w, "INTMAX", comp.types.intmax);
+ try comp.generateIntMaxAndWidth(w, "SIZE", comp.types.size);
+ try comp.generateIntMaxAndWidth(w, "UINTMAX", comp.types.intmax.makeIntegerUnsigned());
+ try comp.generateIntMaxAndWidth(w, "PTRDIFF", comp.types.ptrdiff);
+ try comp.generateIntMaxAndWidth(w, "INTPTR", comp.types.intptr);
+ try comp.generateIntMaxAndWidth(w, "UINTPTR", comp.types.intptr.makeIntegerUnsigned());
+
+ // int widths
+ try w.print("#define __BITINT_MAXWIDTH__ {d}\n", .{bit_int_max_bits});
+
+ // sizeof types
+ try comp.generateSizeofType(w, "__SIZEOF_FLOAT__", .{ .specifier = .float });
+ try comp.generateSizeofType(w, "__SIZEOF_DOUBLE__", .{ .specifier = .double });
+ try comp.generateSizeofType(w, "__SIZEOF_LONG_DOUBLE__", .{ .specifier = .long_double });
+ try comp.generateSizeofType(w, "__SIZEOF_SHORT__", .{ .specifier = .short });
+ try comp.generateSizeofType(w, "__SIZEOF_INT__", .{ .specifier = .int });
+ try comp.generateSizeofType(w, "__SIZEOF_LONG__", .{ .specifier = .long });
+ try comp.generateSizeofType(w, "__SIZEOF_LONG_LONG__", .{ .specifier = .long_long });
+ try comp.generateSizeofType(w, "__SIZEOF_POINTER__", .{ .specifier = .pointer });
+ try comp.generateSizeofType(w, "__SIZEOF_PTRDIFF_T__", comp.types.ptrdiff);
+ try comp.generateSizeofType(w, "__SIZEOF_SIZE_T__", comp.types.size);
+ try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar);
+ // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer });
+
+ // various int types
+ const mapper = comp.string_interner.getSlowTypeMapper();
+ try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts);
+ try generateTypeMacro(w, mapper, "__UINTPTR_TYPE__", comp.types.intptr.makeIntegerUnsigned(), comp.langopts);
+
+ try generateTypeMacro(w, mapper, "__INTMAX_TYPE__", comp.types.intmax, comp.langopts);
+ try comp.generateSuffixMacro("__INTMAX", w, comp.types.intptr);
+
+ try generateTypeMacro(w, mapper, "__UINTMAX_TYPE__", comp.types.intmax.makeIntegerUnsigned(), comp.langopts);
+ try comp.generateSuffixMacro("__UINTMAX", w, comp.types.intptr.makeIntegerUnsigned());
+
+ try generateTypeMacro(w, mapper, "__PTRDIFF_TYPE__", comp.types.ptrdiff, comp.langopts);
+ try generateTypeMacro(w, mapper, "__SIZE_TYPE__", comp.types.size, comp.langopts);
+ try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts);
+
+ try comp.generateExactWidthTypes(w, mapper);
+
+ if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| {
+ try generateFloatMacros(w, "FLT16", half, "F16");
+ }
+ try generateFloatMacros(w, "FLT", target_util.FPSemantics.forType(.float, comp.target), "F");
+ try generateFloatMacros(w, "DBL", target_util.FPSemantics.forType(.double, comp.target), "");
+ try generateFloatMacros(w, "LDBL", target_util.FPSemantics.forType(.longdouble, comp.target), "L");
+
+ // TODO: clang treats __FLT_EVAL_METHOD__ as a special-cased macro because evaluating it within a scope
+ // where `#pragma clang fp eval_method(X)` has been called produces an error diagnostic.
+ const flt_eval_method = comp.langopts.fp_eval_method orelse target_util.defaultFpEvalMethod(comp.target);
+ try w.print("#define __FLT_EVAL_METHOD__ {d}\n", .{@intFromEnum(flt_eval_method)});
+
+ try w.writeAll(
+ \\#define __FLT_RADIX__ 2
+ \\#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+ \\
+ );
+
+ return comp.addSourceFromBuffer("<builtin>", buf.items);
+}
+
+fn generateFloatMacros(w: anytype, prefix: []const u8, semantics: target_util.FPSemantics, ext: []const u8) !void {
+ const denormMin = semantics.chooseValue(
+ []const u8,
+ .{
+ "5.9604644775390625e-8",
+ "1.40129846e-45",
+ "4.9406564584124654e-324",
+ "3.64519953188247460253e-4951",
+ "4.94065645841246544176568792868221e-324",
+ "6.47517511943802511092443895822764655e-4966",
+ },
+ );
+ const digits = semantics.chooseValue(i32, .{ 3, 6, 15, 18, 31, 33 });
+ const decimalDigits = semantics.chooseValue(i32, .{ 5, 9, 17, 21, 33, 36 });
+ const epsilon = semantics.chooseValue(
+ []const u8,
+ .{
+ "9.765625e-4",
+ "1.19209290e-7",
+ "2.2204460492503131e-16",
+ "1.08420217248550443401e-19",
+ "4.94065645841246544176568792868221e-324",
+ "1.92592994438723585305597794258492732e-34",
+ },
+ );
+ const mantissaDigits = semantics.chooseValue(i32, .{ 11, 24, 53, 64, 106, 113 });
+
+ const min10Exp = semantics.chooseValue(i32, .{ -4, -37, -307, -4931, -291, -4931 });
+ const max10Exp = semantics.chooseValue(i32, .{ 4, 38, 308, 4932, 308, 4932 });
+
+ const minExp = semantics.chooseValue(i32, .{ -13, -125, -1021, -16381, -968, -16381 });
+ const maxExp = semantics.chooseValue(i32, .{ 16, 128, 1024, 16384, 1024, 16384 });
+
+ const min = semantics.chooseValue(
+ []const u8,
+ .{
+ "6.103515625e-5",
+ "1.17549435e-38",
+ "2.2250738585072014e-308",
+ "3.36210314311209350626e-4932",
+ "2.00416836000897277799610805135016e-292",
+ "3.36210314311209350626267781732175260e-4932",
+ },
+ );
+ const max = semantics.chooseValue(
+ []const u8,
+ .{
+ "6.5504e+4",
+ "3.40282347e+38",
+ "1.7976931348623157e+308",
+ "1.18973149535723176502e+4932",
+ "1.79769313486231580793728971405301e+308",
+ "1.18973149535723176508575932662800702e+4932",
+ },
+ );
+
+ var defPrefix = std.BoundedArray(u8, 32).init(0) catch unreachable;
+ defPrefix.writer().print("__{s}_", .{prefix}) catch return error.OutOfMemory;
+
+ const prefix_slice = defPrefix.constSlice();
+
+ try w.print("#define {s}DENORM_MIN__ {s}{s}\n", .{ prefix_slice, denormMin, ext });
+ try w.print("#define {s}HAS_DENORM__\n", .{prefix_slice});
+ try w.print("#define {s}DIG__ {d}\n", .{ prefix_slice, digits });
+ try w.print("#define {s}DECIMAL_DIG__ {d}\n", .{ prefix_slice, decimalDigits });
+
+ try w.print("#define {s}EPSILON__ {s}{s}\n", .{ prefix_slice, epsilon, ext });
+ try w.print("#define {s}HAS_INFINITY__\n", .{prefix_slice});
+ try w.print("#define {s}HAS_QUIET_NAN__\n", .{prefix_slice});
+ try w.print("#define {s}MANT_DIG__ {d}\n", .{ prefix_slice, mantissaDigits });
+
+ try w.print("#define {s}MAX_10_EXP__ {d}\n", .{ prefix_slice, max10Exp });
+ try w.print("#define {s}MAX_EXP__ {d}\n", .{ prefix_slice, maxExp });
+ try w.print("#define {s}MAX__ {s}{s}\n", .{ prefix_slice, max, ext });
+
+ try w.print("#define {s}MIN_10_EXP__ ({d})\n", .{ prefix_slice, min10Exp });
+ try w.print("#define {s}MIN_EXP__ ({d})\n", .{ prefix_slice, minExp });
+ try w.print("#define {s}MIN__ {s}{s}\n", .{ prefix_slice, min, ext });
+}
+
+fn generateTypeMacro(w: anytype, mapper: StringInterner.TypeMapper, name: []const u8, ty: Type, langopts: LangOpts) !void {
+ try w.print("#define {s} ", .{name});
+ try ty.print(mapper, langopts, w);
+ try w.writeByte('\n');
+}
+
+fn generateBuiltinTypes(comp: *Compilation) !void {
+ const os = comp.target.os.tag;
+ const wchar: Type = switch (comp.target.cpu.arch) {
+ .xcore => .{ .specifier = .uchar },
+ .ve, .msp430 => .{ .specifier = .uint },
+ .arm, .armeb, .thumb, .thumbeb => .{
+ .specifier = if (os != .windows and os != .netbsd and os != .openbsd) .uint else .int,
+ },
+ .aarch64, .aarch64_be, .aarch64_32 => .{
+ .specifier = if (!os.isDarwin() and os != .netbsd) .uint else .int,
+ },
+ .x86_64, .x86 => .{ .specifier = if (os == .windows) .ushort else .int },
+ else => .{ .specifier = .int },
+ };
+
+ const ptr_width = comp.target.ptrBitWidth();
+ const ptrdiff = if (os == .windows and ptr_width == 64)
+ Type{ .specifier = .long_long }
+ else switch (ptr_width) {
+ 16 => Type{ .specifier = .int },
+ 32 => Type{ .specifier = .int },
+ 64 => Type{ .specifier = .long },
+ else => unreachable,
+ };
+
+ const size = if (os == .windows and ptr_width == 64)
+ Type{ .specifier = .ulong_long }
+ else switch (ptr_width) {
+ 16 => Type{ .specifier = .uint },
+ 32 => Type{ .specifier = .uint },
+ 64 => Type{ .specifier = .ulong },
+ else => unreachable,
+ };
+
+ const va_list = try comp.generateVaListType();
+
+ const pid_t: Type = switch (os) {
+ .haiku => .{ .specifier = .long },
+ // Todo: pid_t is required to "a signed integer type"; are there any systems
+ // on which it is `short int`?
+ else => .{ .specifier = .int },
+ };
+
+ const intmax = target_util.intMaxType(comp.target);
+ const intptr = target_util.intPtrType(comp.target);
+ const int16 = target_util.int16Type(comp.target);
+ const int64 = target_util.int64Type(comp.target);
+
+ comp.types = .{
+ .wchar = wchar,
+ .ptrdiff = ptrdiff,
+ .size = size,
+ .va_list = va_list,
+ .pid_t = pid_t,
+ .intmax = intmax,
+ .intptr = intptr,
+ .int16 = int16,
+ .int64 = int64,
+ };
+
+ try comp.generateNsConstantStringType();
+}
+
+fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 {
+ const ty = Type{ .specifier = specifier };
+ return ty.sizeof(comp).?;
+}
+
+fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StringInterner.TypeMapper) !void {
+ try comp.generateExactWidthType(w, mapper, .schar);
+
+ if (comp.intSize(.short) > comp.intSize(.char)) {
+ try comp.generateExactWidthType(w, mapper, .short);
+ }
+
+ if (comp.intSize(.int) > comp.intSize(.short)) {
+ try comp.generateExactWidthType(w, mapper, .int);
+ }
+
+ if (comp.intSize(.long) > comp.intSize(.int)) {
+ try comp.generateExactWidthType(w, mapper, .long);
+ }
+
+ if (comp.intSize(.long_long) > comp.intSize(.long)) {
+ try comp.generateExactWidthType(w, mapper, .long_long);
+ }
+
+ try comp.generateExactWidthType(w, mapper, .uchar);
+ try comp.generateExactWidthIntMax(w, .uchar);
+ try comp.generateExactWidthIntMax(w, .schar);
+
+ if (comp.intSize(.short) > comp.intSize(.char)) {
+ try comp.generateExactWidthType(w, mapper, .ushort);
+ try comp.generateExactWidthIntMax(w, .ushort);
+ try comp.generateExactWidthIntMax(w, .short);
+ }
+
+ if (comp.intSize(.int) > comp.intSize(.short)) {
+ try comp.generateExactWidthType(w, mapper, .uint);
+ try comp.generateExactWidthIntMax(w, .uint);
+ try comp.generateExactWidthIntMax(w, .int);
+ }
+
+ if (comp.intSize(.long) > comp.intSize(.int)) {
+ try comp.generateExactWidthType(w, mapper, .ulong);
+ try comp.generateExactWidthIntMax(w, .ulong);
+ try comp.generateExactWidthIntMax(w, .long);
+ }
+
+ if (comp.intSize(.long_long) > comp.intSize(.long)) {
+ try comp.generateExactWidthType(w, mapper, .ulong_long);
+ try comp.generateExactWidthIntMax(w, .ulong_long);
+ try comp.generateExactWidthIntMax(w, .long_long);
+ }
+}
+
+fn generateFmt(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
+ const unsigned = ty.isUnsignedInt(comp);
+ const modifier = ty.formatModifier();
+ const formats = if (unsigned) "ouxX" else "di";
+ for (formats) |c| {
+ try w.print("#define {s}_FMT{c}__ \"{s}{c}\"\n", .{ prefix, c, modifier, c });
+ }
+}
+
+fn generateSuffixMacro(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
+ return w.print("#define {s}_C_SUFFIX__ {s}\n", .{ prefix, ty.intValueSuffix(comp) });
+}
+
+/// Generate the following for ty:
+/// Name macro (e.g. #define __UINT32_TYPE__ unsigned int)
+/// Format strings (e.g. #define __UINT32_FMTu__ "u")
+/// Suffix macro (e.g. #define __UINT32_C_SUFFIX__ U)
+fn generateExactWidthType(comp: *const Compilation, w: anytype, mapper: StringInterner.TypeMapper, specifier: Type.Specifier) !void {
+ var ty = Type{ .specifier = specifier };
+ const width = 8 * ty.sizeof(comp).?;
+ const unsigned = ty.isUnsignedInt(comp);
+
+ if (width == 16) {
+ ty = if (unsigned) comp.types.int16.makeIntegerUnsigned() else comp.types.int16;
+ } else if (width == 64) {
+ ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
+ }
+
+ var prefix = std.BoundedArray(u8, 16).init(0) catch unreachable;
+ prefix.writer().print("{s}{d}", .{ if (unsigned) "__UINT" else "__INT", width }) catch return error.OutOfMemory;
+
+ {
+ const len = prefix.len;
+ defer prefix.resize(len) catch unreachable; // restoring previous size
+ prefix.appendSliceAssumeCapacity("_TYPE__");
+ try generateTypeMacro(w, mapper, prefix.constSlice(), ty, comp.langopts);
+ }
+
+ try comp.generateFmt(prefix.constSlice(), w, ty);
+ try comp.generateSuffixMacro(prefix.constSlice(), w, ty);
+}
+
+pub fn hasHalfPrecisionFloatABI(comp: *const Compilation) bool {
+ return comp.langopts.allow_half_args_and_returns or target_util.hasHalfPrecisionFloatABI(comp.target);
+}
+
+fn generateNsConstantStringType(comp: *Compilation) !void {
+ comp.types.ns_constant_string.record = .{
+ .name = try comp.intern("__NSConstantString_tag"),
+ .fields = &comp.types.ns_constant_string.fields,
+ .field_attributes = null,
+ .type_layout = undefined,
+ };
+ const const_int_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.int_ty } };
+ const const_char_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.char_ty } };
+
+ comp.types.ns_constant_string.fields[0] = .{ .name = try comp.intern("isa"), .ty = const_int_ptr };
+ comp.types.ns_constant_string.fields[1] = .{ .name = try comp.intern("flags"), .ty = .{ .specifier = .int } };
+ comp.types.ns_constant_string.fields[2] = .{ .name = try comp.intern("str"), .ty = const_char_ptr };
+ comp.types.ns_constant_string.fields[3] = .{ .name = try comp.intern("length"), .ty = .{ .specifier = .long } };
+ comp.types.ns_constant_string.ty = .{ .specifier = .@"struct", .data = .{ .record = &comp.types.ns_constant_string.record } };
+ record_layout.compute(&comp.types.ns_constant_string.record, comp.types.ns_constant_string.ty, comp, null);
+}
+
+fn generateVaListType(comp: *Compilation) !Type {
+ const Kind = enum { char_ptr, void_ptr, aarch64_va_list, x86_64_va_list };
+ const kind: Kind = switch (comp.target.cpu.arch) {
+ .aarch64 => switch (comp.target.os.tag) {
+ .windows => @as(Kind, .char_ptr),
+ .ios, .macos, .tvos, .watchos => .char_ptr,
+ else => .aarch64_va_list,
+ },
+ .sparc, .wasm32, .wasm64, .bpfel, .bpfeb, .riscv32, .riscv64, .avr, .spirv32, .spirv64 => .void_ptr,
+ .powerpc => switch (comp.target.os.tag) {
+ .ios, .macos, .tvos, .watchos, .aix => @as(Kind, .char_ptr),
+ else => return Type{ .specifier = .void }, // unknown
+ },
+ .x86, .msp430 => .char_ptr,
+ .x86_64 => switch (comp.target.os.tag) {
+ .windows => @as(Kind, .char_ptr),
+ else => .x86_64_va_list,
+ },
+ else => return Type{ .specifier = .void }, // unknown
+ };
+
+ // TODO this might be bad?
+ const arena = comp.diag.arena.allocator();
+
+ var ty: Type = undefined;
+ switch (kind) {
+ .char_ptr => ty = .{ .specifier = .char },
+ .void_ptr => ty = .{ .specifier = .void },
+ .aarch64_va_list => {
+ const record_ty = try arena.create(Type.Record);
+ record_ty.* = .{
+ .name = try comp.intern("__va_list_tag"),
+ .fields = try arena.alloc(Type.Record.Field, 5),
+ .field_attributes = null,
+ .type_layout = undefined, // computed below
+ };
+ const void_ty = try arena.create(Type);
+ void_ty.* = .{ .specifier = .void };
+ const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
+ record_ty.fields[0] = .{ .name = try comp.intern("__stack"), .ty = void_ptr };
+ record_ty.fields[1] = .{ .name = try comp.intern("__gr_top"), .ty = void_ptr };
+ record_ty.fields[2] = .{ .name = try comp.intern("__vr_top"), .ty = void_ptr };
+ record_ty.fields[3] = .{ .name = try comp.intern("__gr_offs"), .ty = .{ .specifier = .int } };
+ record_ty.fields[4] = .{ .name = try comp.intern("__vr_offs"), .ty = .{ .specifier = .int } };
+ ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
+ record_layout.compute(record_ty, ty, comp, null);
+ },
+ .x86_64_va_list => {
+ const record_ty = try arena.create(Type.Record);
+ record_ty.* = .{
+ .name = try comp.intern("__va_list_tag"),
+ .fields = try arena.alloc(Type.Record.Field, 4),
+ .field_attributes = null,
+ .type_layout = undefined, // computed below
+ };
+ const void_ty = try arena.create(Type);
+ void_ty.* = .{ .specifier = .void };
+ const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
+ record_ty.fields[0] = .{ .name = try comp.intern("gp_offset"), .ty = .{ .specifier = .uint } };
+ record_ty.fields[1] = .{ .name = try comp.intern("fp_offset"), .ty = .{ .specifier = .uint } };
+ record_ty.fields[2] = .{ .name = try comp.intern("overflow_arg_area"), .ty = void_ptr };
+ record_ty.fields[3] = .{ .name = try comp.intern("reg_save_area"), .ty = void_ptr };
+ ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
+ record_layout.compute(record_ty, ty, comp, null);
+ },
+ }
+ if (kind == .char_ptr or kind == .void_ptr) {
+ const elem_ty = try arena.create(Type);
+ elem_ty.* = ty;
+ ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
+ } else {
+ const arr_ty = try arena.create(Type.Array);
+ arr_ty.* = .{ .len = 1, .elem = ty };
+ ty = Type{ .specifier = .array, .data = .{ .array = arr_ty } };
+ }
+
+ return ty;
+}
+
+fn generateIntMax(comp: *const Compilation, w: anytype, name: []const u8, ty: Type) !void {
+ const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
+ const unsigned = ty.isUnsignedInt(comp);
+ const max = if (bit_count == 128)
+ @as(u128, if (unsigned) std.math.maxInt(u128) else std.math.maxInt(u128))
+ else
+ ty.maxInt(comp);
+ try w.print("#define __{s}_MAX__ {d}{s}\n", .{ name, max, ty.intValueSuffix(comp) });
+}
+
+fn generateExactWidthIntMax(comp: *const Compilation, w: anytype, specifier: Type.Specifier) !void {
+ var ty = Type{ .specifier = specifier };
+ const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
+ const unsigned = ty.isUnsignedInt(comp);
+
+ if (bit_count == 64) {
+ ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
+ }
+
+ var name = std.BoundedArray(u8, 6).init(0) catch unreachable;
+ name.writer().print("{s}{d}", .{ if (unsigned) "UINT" else "INT", bit_count }) catch return error.OutOfMemory;
+
+ return comp.generateIntMax(w, name.constSlice(), ty);
+}
+
+fn generateIntWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
+ try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, 8 * ty.sizeof(comp).? });
+}
+
+fn generateIntMaxAndWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
+ try comp.generateIntMax(w, name, ty);
+ try comp.generateIntWidth(w, name, ty);
+}
+
+fn generateSizeofType(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
+ try w.print("#define {s} {d}\n", .{ name, ty.sizeof(comp).? });
+}
+
+pub fn nextLargestIntSameSign(comp: *const Compilation, ty: Type) ?Type {
+ assert(ty.isInt());
+ const specifiers = if (ty.isUnsignedInt(comp))
+ [_]Type.Specifier{ .short, .int, .long, .long_long }
+ else
+ [_]Type.Specifier{ .ushort, .uint, .ulong, .ulong_long };
+ const size = ty.sizeof(comp).?;
+ for (specifiers) |specifier| {
+ const candidate = Type{ .specifier = specifier };
+ if (candidate.sizeof(comp).? > size) return candidate;
+ }
+ return null;
+}
+
+/// If `enum E { ... }` syntax has a fixed underlying integer type regardless of the presence of
+/// __attribute__((packed)) or the range of values of the corresponding enumerator constants,
+/// specify it here.
+/// TODO: likely incomplete
+pub fn fixedEnumTagSpecifier(comp: *const Compilation) ?Type.Specifier {
+ switch (comp.langopts.emulate) {
+ .msvc => return .int,
+ .clang => if (comp.target.os.tag == .windows) return .int,
+ .gcc => {},
+ }
+ return null;
+}
+
+pub fn getCharSignedness(comp: *const Compilation) std.builtin.Signedness {
+ return comp.langopts.char_signedness_override orelse comp.target.charSignedness();
+}
+
+pub fn defineSystemIncludes(comp: *Compilation, aro_dir: []const u8) !void {
+ var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+ const allocator = stack_fallback.get();
+ var search_path = aro_dir;
+ while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) {
+ var base_dir = std.fs.cwd().openDir(dirname, .{}) catch continue;
+ defer base_dir.close();
+
+ base_dir.access("include/stddef.h", .{}) catch continue;
+ const path = try std.fs.path.join(comp.gpa, &.{ dirname, "include" });
+ errdefer comp.gpa.free(path);
+ try comp.system_include_dirs.append(path);
+ break;
+ } else return error.AroIncludeNotFound;
+
+ if (comp.target.os.tag == .linux) {
+ const triple_str = try comp.target.linuxTriple(allocator);
+ defer allocator.free(triple_str);
+
+ const multiarch_path = try std.fs.path.join(allocator, &.{ "/usr/include", triple_str });
+ defer allocator.free(multiarch_path);
+
+ if (!std.meta.isError(std.fs.accessAbsolute(multiarch_path, .{}))) {
+ const duped = try comp.gpa.dupe(u8, multiarch_path);
+ errdefer comp.gpa.free(duped);
+ try comp.system_include_dirs.append(duped);
+ }
+ }
+ const usr_include = try comp.gpa.dupe(u8, "/usr/include");
+ errdefer comp.gpa.free(usr_include);
+ try comp.system_include_dirs.append(usr_include);
+}
+
+pub fn getSource(comp: *const Compilation, id: Source.Id) Source {
+ if (id == .generated) return .{
+ .path = "<scratch space>",
+ .buf = comp.generated_buf.items,
+ .id = .generated,
+ .splice_locs = &.{},
+ };
+ return comp.sources.values()[@intFromEnum(id) - 2];
+}
+
+/// Creates a Source from the contents of `reader` and adds it to the Compilation
+/// Performs newline splicing, line-ending normalization to '\n', and UTF-8 validation.
+/// caller retains ownership of `path`
+/// `expected_size` will be allocated to hold the contents of `reader` and *must* be at least
+/// as large as the entire contents of `reader`.
+/// To add a pre-existing buffer as a Source, see addSourceFromBuffer
+/// To add a file's contents given its path, see addSourceFromPath
+pub fn addSourceFromReader(comp: *Compilation, reader: anytype, path: []const u8, expected_size: u32) !Source {
+ var contents = try comp.gpa.alloc(u8, expected_size);
+ errdefer comp.gpa.free(contents);
+
+ const duped_path = try comp.gpa.dupe(u8, path);
+ errdefer comp.gpa.free(duped_path);
+
+ var splice_list = std.ArrayList(u32).init(comp.gpa);
+ defer splice_list.deinit();
+
+ const source_id: Source.Id = @enumFromInt(comp.sources.count() + 2);
+
+ var i: u32 = 0;
+ var backslash_loc: u32 = undefined;
+ var state: enum {
+ beginning_of_file,
+ bom1,
+ bom2,
+ start,
+ back_slash,
+ cr,
+ back_slash_cr,
+ trailing_ws,
+ } = .beginning_of_file;
+ var line: u32 = 1;
+
+ while (true) {
+ const byte = reader.readByte() catch |err| switch (err) {
+ error.EndOfStream => break,
+ else => |e| return e,
+ };
+ contents[i] = byte;
+
+ switch (byte) {
+ '\r' => {
+ switch (state) {
+ .start, .cr, .beginning_of_file => {
+ state = .start;
+ line += 1;
+ state = .cr;
+ contents[i] = '\n';
+ i += 1;
+ },
+ .back_slash, .trailing_ws, .back_slash_cr => {
+ i = backslash_loc;
+ try splice_list.append(i);
+ if (state == .trailing_ws) {
+ try comp.diag.add(.{
+ .tag = .backslash_newline_escape,
+ .loc = .{ .id = source_id, .byte_offset = i, .line = line },
+ }, &.{});
+ }
+ state = if (state == .back_slash_cr) .cr else .back_slash_cr;
+ },
+ .bom1, .bom2 => break, // invalid utf-8
+ }
+ },
+ '\n' => {
+ switch (state) {
+ .start, .beginning_of_file => {
+ state = .start;
+ line += 1;
+ i += 1;
+ },
+ .cr, .back_slash_cr => {},
+ .back_slash, .trailing_ws => {
+ i = backslash_loc;
+ if (state == .back_slash or state == .trailing_ws) {
+ try splice_list.append(i);
+ }
+ if (state == .trailing_ws) {
+ try comp.diag.add(.{
+ .tag = .backslash_newline_escape,
+ .loc = .{ .id = source_id, .byte_offset = i, .line = line },
+ }, &.{});
+ }
+ },
+ .bom1, .bom2 => break,
+ }
+ state = .start;
+ },
+ '\\' => {
+ backslash_loc = i;
+ state = .back_slash;
+ i += 1;
+ },
+ '\t', '\x0B', '\x0C', ' ' => {
+ switch (state) {
+ .start, .trailing_ws => {},
+ .beginning_of_file => state = .start,
+ .cr, .back_slash_cr => state = .start,
+ .back_slash => state = .trailing_ws,
+ .bom1, .bom2 => break,
+ }
+ i += 1;
+ },
+ '\xEF' => {
+ i += 1;
+ state = switch (state) {
+ .beginning_of_file => .bom1,
+ else => .start,
+ };
+ },
+ '\xBB' => {
+ i += 1;
+ state = switch (state) {
+ .bom1 => .bom2,
+ else => .start,
+ };
+ },
+ '\xBF' => {
+ switch (state) {
+ .bom2 => i = 0, // rewind and overwrite the BOM
+ else => i += 1,
+ }
+ state = .start;
+ },
+ else => {
+ i += 1;
+ state = .start;
+ },
+ }
+ }
+
+ const splice_locs = try splice_list.toOwnedSlice();
+ errdefer comp.gpa.free(splice_locs);
+
+ if (i != contents.len) contents = try comp.gpa.realloc(contents, i);
+
+ var source = Source{
+ .id = source_id,
+ .path = duped_path,
+ .buf = contents,
+ .splice_locs = splice_locs,
+ };
+
+ try comp.sources.put(duped_path, source);
+ if (source.offsetOfInvalidUtf8()) |offset| {
+ try comp.invalid_utf8_locs.putNoClobber(comp.gpa, source_id, offset);
+ }
+ return source;
+}
+
+/// Caller retains ownership of `path` and `buf`.
+pub fn addSourceFromBuffer(comp: *Compilation, path: []const u8, buf: []const u8) !Source {
+ if (comp.sources.get(path)) |some| return some;
+
+ const size = std.math.cast(u32, buf.len) orelse return error.StreamTooLong;
+ var buf_reader = std.io.fixedBufferStream(buf);
+
+ return comp.addSourceFromReader(buf_reader.reader(), path, size);
+}
+
+/// Caller retains ownership of `path`
+pub fn addSourceFromPath(comp: *Compilation, path: []const u8) !Source {
+ if (comp.sources.get(path)) |some| return some;
+
+ if (mem.indexOfScalar(u8, path, 0) != null) {
+ return error.FileNotFound;
+ }
+
+ const file = try std.fs.cwd().openFile(path, .{});
+ defer file.close();
+
+ const size = std.math.cast(u32, try file.getEndPos()) orelse return error.StreamTooLong;
+ var buf_reader = std.io.bufferedReader(file.reader());
+
+ return comp.addSourceFromReader(buf_reader.reader(), path, size);
+}
+
+pub const IncludeDirIterator = struct {
+ comp: *const Compilation,
+ cwd_source_id: ?Source.Id,
+ include_dirs_idx: usize = 0,
+ sys_include_dirs_idx: usize = 0,
+
+ fn next(self: *IncludeDirIterator) ?[]const u8 {
+ if (self.cwd_source_id) |source_id| {
+ self.cwd_source_id = null;
+ const path = self.comp.getSource(source_id).path;
+ return std.fs.path.dirname(path) orelse ".";
+ }
+ if (self.include_dirs_idx < self.comp.include_dirs.items.len) {
+ defer self.include_dirs_idx += 1;
+ return self.comp.include_dirs.items[self.include_dirs_idx];
+ }
+ if (self.sys_include_dirs_idx < self.comp.system_include_dirs.items.len) {
+ defer self.sys_include_dirs_idx += 1;
+ return self.comp.system_include_dirs.items[self.sys_include_dirs_idx];
+ }
+ return null;
+ }
+
+ /// Returned value must be freed by allocator
+ fn nextWithFile(self: *IncludeDirIterator, filename: []const u8, allocator: Allocator) !?[]const u8 {
+ while (self.next()) |dir| {
+ return try std.fs.path.join(allocator, &.{ dir, filename });
+ }
+ return null;
+ }
+
+ /// Advance the iterator until it finds an include directory that matches
+ /// the directory which contains `source`.
+ fn skipUntilDirMatch(self: *IncludeDirIterator, source: Source.Id) void {
+ const path = self.comp.getSource(source).path;
+ const includer_path = std.fs.path.dirname(path) orelse ".";
+ while (self.next()) |dir| {
+ if (mem.eql(u8, includer_path, dir)) break;
+ }
+ }
+};
+
+pub fn hasInclude(
+ comp: *const Compilation,
+ filename: []const u8,
+ includer_token_source: Source.Id,
+ /// angle bracket vs quotes
+ include_type: IncludeType,
+ /// __has_include vs __has_include_next
+ which: WhichInclude,
+) !bool {
+ const cwd = std.fs.cwd();
+ if (std.fs.path.isAbsolute(filename)) {
+ if (which == .next) return false;
+ return !std.meta.isError(cwd.access(filename, .{}));
+ }
+
+ const cwd_source_id = switch (include_type) {
+ .quotes => switch (which) {
+ .first => includer_token_source,
+ .next => null,
+ },
+ .angle_brackets => null,
+ };
+ var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
+ if (which == .next) {
+ it.skipUntilDirMatch(includer_token_source);
+ }
+
+ var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+
+ while (try it.nextWithFile(filename, stack_fallback.get())) |path| {
+ defer stack_fallback.get().free(path);
+ if (!std.meta.isError(cwd.access(path, .{}))) return true;
+ }
+ return false;
+}
+
+pub const WhichInclude = enum {
+ first,
+ next,
+};
+
+pub const IncludeType = enum {
+ quotes,
+ angle_brackets,
+};
+
+fn getFileContents(comp: *Compilation, path: []const u8) ![]const u8 {
+ if (mem.indexOfScalar(u8, path, 0) != null) {
+ return error.FileNotFound;
+ }
+
+ const file = try std.fs.cwd().openFile(path, .{});
+ defer file.close();
+
+ return file.readToEndAlloc(comp.gpa, std.math.maxInt(u32));
+}
+
+pub fn findEmbed(
+ comp: *Compilation,
+ filename: []const u8,
+ includer_token_source: Source.Id,
+ /// angle bracket vs quotes
+ include_type: IncludeType,
+) !?[]const u8 {
+ if (std.fs.path.isAbsolute(filename)) {
+ return if (comp.getFileContents(filename)) |some|
+ some
+ else |err| switch (err) {
+ error.OutOfMemory => |e| return e,
+ else => null,
+ };
+ }
+
+ const cwd_source_id = switch (include_type) {
+ .quotes => includer_token_source,
+ .angle_brackets => null,
+ };
+ var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
+ var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+
+ while (try it.nextWithFile(filename, stack_fallback.get())) |path| {
+ defer stack_fallback.get().free(path);
+ if (comp.getFileContents(path)) |some|
+ return some
+ else |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ else => {},
+ }
+ }
+ return null;
+}
+
+pub fn findInclude(
+ comp: *Compilation,
+ filename: []const u8,
+ includer_token_source: Source.Id,
+ /// angle bracket vs quotes
+ include_type: IncludeType,
+ /// include vs include_next
+ which: WhichInclude,
+) !?Source {
+ if (std.fs.path.isAbsolute(filename)) {
+ if (which == .next) return null;
+ return if (comp.addSourceFromPath(filename)) |some|
+ some
+ else |err| switch (err) {
+ error.OutOfMemory => |e| return e,
+ else => null,
+ };
+ }
+ const cwd_source_id = switch (include_type) {
+ .quotes => switch (which) {
+ .first => includer_token_source,
+ .next => null,
+ },
+ .angle_brackets => null,
+ };
+ var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
+
+ if (which == .next) {
+ it.skipUntilDirMatch(includer_token_source);
+ }
+
+ var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+ while (try it.nextWithFile(filename, stack_fallback.get())) |path| {
+ defer stack_fallback.get().free(path);
+ if (comp.addSourceFromPath(path)) |some|
+ return some
+ else |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ else => {},
+ }
+ }
+ return null;
+}
+
+pub fn addPragmaHandler(comp: *Compilation, name: []const u8, handler: *Pragma) Allocator.Error!void {
+ try comp.pragma_handlers.putNoClobber(name, handler);
+}
+
+pub fn addDefaultPragmaHandlers(comp: *Compilation) Allocator.Error!void {
+ const GCC = @import("pragmas/gcc.zig");
+ var gcc = try GCC.init(comp.gpa);
+ errdefer gcc.deinit(gcc, comp);
+
+ const Once = @import("pragmas/once.zig");
+ var once = try Once.init(comp.gpa);
+ errdefer once.deinit(once, comp);
+
+ const Message = @import("pragmas/message.zig");
+ var message = try Message.init(comp.gpa);
+ errdefer message.deinit(message, comp);
+
+ const Pack = @import("pragmas/pack.zig");
+ var pack = try Pack.init(comp.gpa);
+ errdefer pack.deinit(pack, comp);
+
+ try comp.addPragmaHandler("GCC", gcc);
+ try comp.addPragmaHandler("once", once);
+ try comp.addPragmaHandler("message", message);
+ try comp.addPragmaHandler("pack", pack);
+}
+
+pub fn getPragma(comp: *Compilation, name: []const u8) ?*Pragma {
+ return comp.pragma_handlers.get(name);
+}
+
+const PragmaEvent = enum {
+ before_preprocess,
+ before_parse,
+ after_parse,
+};
+
+pub fn pragmaEvent(comp: *Compilation, event: PragmaEvent) void {
+ for (comp.pragma_handlers.values()) |pragma| {
+ const maybe_func = switch (event) {
+ .before_preprocess => pragma.beforePreprocess,
+ .before_parse => pragma.beforeParse,
+ .after_parse => pragma.afterParse,
+ };
+ if (maybe_func) |func| func(pragma, comp);
+ }
+}
+
+pub fn hasBuiltin(comp: *const Compilation, name: []const u8) bool {
+ if (std.mem.eql(u8, name, "__builtin_va_arg") or
+ std.mem.eql(u8, name, "__builtin_choose_expr") or
+ std.mem.eql(u8, name, "__builtin_bitoffsetof") or
+ std.mem.eql(u8, name, "__builtin_offsetof") or
+ std.mem.eql(u8, name, "__builtin_types_compatible_p")) return true;
+
+ @setEvalBranchQuota(10_000);
+ const tag = std.meta.stringToEnum(BuiltinFunction.Tag, name) orelse return false;
+ const builtin = BuiltinFunction.fromTag(tag);
+ return comp.hasBuiltinFunction(builtin);
+}
+
+pub fn hasBuiltinFunction(comp: *const Compilation, builtin: BuiltinFunction) bool {
+ if (!target_util.builtinEnabled(comp.target, builtin.properties.target_set)) return false;
+
+ switch (builtin.properties.language) {
+ .all_languages => return true,
+ .all_ms_languages => return comp.langopts.emulate == .msvc,
+ .gnu_lang, .all_gnu_languages => return comp.langopts.standard.isGNU(),
+ }
+}
+
+pub const renderErrors = Diagnostics.render;
+
+test "addSourceFromReader" {
+ const Test = struct {
+ fn addSourceFromReader(str: []const u8, expected: []const u8, warning_count: u32, splices: []const u32) !void {
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+
+ var buf_reader = std.io.fixedBufferStream(str);
+ const source = try comp.addSourceFromReader(buf_reader.reader(), "path", @intCast(str.len));
+
+ try std.testing.expectEqualStrings(expected, source.buf);
+ try std.testing.expectEqual(warning_count, @as(u32, @intCast(comp.diag.list.items.len)));
+ try std.testing.expectEqualSlices(u32, splices, source.splice_locs);
+ }
+
+ fn withAllocationFailures(allocator: std.mem.Allocator) !void {
+ var comp = Compilation.init(allocator);
+ defer comp.deinit();
+
+ _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n");
+ _ = try comp.addSourceFromBuffer("path", "non-spliced buffer\n");
+ }
+ };
+ try Test.addSourceFromReader("ab\\\nc", "abc", 0, &.{2});
+ try Test.addSourceFromReader("ab\\\rc", "abc", 0, &.{2});
+ try Test.addSourceFromReader("ab\\\r\nc", "abc", 0, &.{2});
+ try Test.addSourceFromReader("ab\\ \nc", "abc", 1, &.{2});
+ try Test.addSourceFromReader("ab\\\t\nc", "abc", 1, &.{2});
+ try Test.addSourceFromReader("ab\\ \t\nc", "abc", 1, &.{2});
+ try Test.addSourceFromReader("ab\\\r \nc", "ab \nc", 0, &.{2});
+ try Test.addSourceFromReader("ab\\\\\nc", "ab\\c", 0, &.{3});
+ try Test.addSourceFromReader("ab\\ \r\nc", "abc", 1, &.{2});
+ try Test.addSourceFromReader("ab\\ \\\nc", "ab\\ c", 0, &.{4});
+ try Test.addSourceFromReader("ab\\\r\\\nc", "abc", 0, &.{ 2, 2 });
+ try Test.addSourceFromReader("ab\\ \rc", "abc", 1, &.{2});
+ try Test.addSourceFromReader("ab\\", "ab\\", 0, &.{});
+ try Test.addSourceFromReader("ab\\\\", "ab\\\\", 0, &.{});
+ try Test.addSourceFromReader("ab\\ ", "ab\\ ", 0, &.{});
+ try Test.addSourceFromReader("ab\\\n", "ab", 0, &.{2});
+ try Test.addSourceFromReader("ab\\\r\n", "ab", 0, &.{2});
+ try Test.addSourceFromReader("ab\\\r", "ab", 0, &.{2});
+
+ // carriage return normalization
+ try Test.addSourceFromReader("ab\r", "ab\n", 0, &.{});
+ try Test.addSourceFromReader("ab\r\r", "ab\n\n", 0, &.{});
+ try Test.addSourceFromReader("ab\r\r\n", "ab\n\n", 0, &.{});
+ try Test.addSourceFromReader("ab\r\r\n\r", "ab\n\n\n", 0, &.{});
+ try Test.addSourceFromReader("\r\\", "\n\\", 0, &.{});
+ try Test.addSourceFromReader("\\\r\\", "\\", 0, &.{0});
+
+ try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.withAllocationFailures, .{});
+}
+
+test "addSourceFromReader - exhaustive check for carriage return elimination" {
+ const alphabet = [_]u8{ '\r', '\n', ' ', '\\', 'a' };
+ const alen = alphabet.len;
+ var buf: [alphabet.len]u8 = [1]u8{alphabet[0]} ** alen;
+
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+
+ var source_count: u32 = 0;
+
+ while (true) {
+ const source = try comp.addSourceFromBuffer(&buf, &buf);
+ source_count += 1;
+ try std.testing.expect(std.mem.indexOfScalar(u8, source.buf, '\r') == null);
+
+ if (std.mem.allEqual(u8, &buf, alphabet[alen - 1])) break;
+
+ var idx = std.mem.indexOfScalar(u8, &alphabet, buf[buf.len - 1]).?;
+ buf[buf.len - 1] = alphabet[(idx + 1) % alen];
+ var j = buf.len - 1;
+ while (j > 0) : (j -= 1) {
+ idx = std.mem.indexOfScalar(u8, &alphabet, buf[j - 1]).?;
+ if (buf[j] == alphabet[0]) buf[j - 1] = alphabet[(idx + 1) % alen] else break;
+ }
+ }
+ try std.testing.expect(source_count == std.math.powi(usize, alen, alen) catch unreachable);
+}
+
+test "ignore BOM at beginning of file" {
+ const BOM = "\xEF\xBB\xBF";
+
+ const Test = struct {
+ fn run(buf: []const u8, input_type: enum { valid_utf8, invalid_utf8 }) !void {
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+
+ var buf_reader = std.io.fixedBufferStream(buf);
+ const source = try comp.addSourceFromReader(buf_reader.reader(), "file.c", @intCast(buf.len));
+ switch (input_type) {
+ .valid_utf8 => {
+ const expected_output = if (mem.startsWith(u8, buf, BOM)) buf[BOM.len..] else buf;
+ try std.testing.expectEqualStrings(expected_output, source.buf);
+ try std.testing.expect(!comp.invalid_utf8_locs.contains(source.id));
+ },
+ .invalid_utf8 => try std.testing.expect(comp.invalid_utf8_locs.contains(source.id)),
+ }
+ }
+ };
+
+ try Test.run(BOM, .valid_utf8);
+ try Test.run(BOM ++ "x", .valid_utf8);
+ try Test.run("x" ++ BOM, .valid_utf8);
+ try Test.run(BOM ++ " ", .valid_utf8);
+ try Test.run(BOM ++ "\n", .valid_utf8);
+ try Test.run(BOM ++ "\\", .valid_utf8);
+
+ try Test.run(BOM[0..1] ++ "x", .invalid_utf8);
+ try Test.run(BOM[0..2] ++ "x", .invalid_utf8);
+ try Test.run(BOM[1..] ++ "x", .invalid_utf8);
+ try Test.run(BOM[2..] ++ "x", .invalid_utf8);
+}
deps/aro/Diagnostics.zig
@@ -0,0 +1,2787 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const Source = @import("Source.zig");
+const Compilation = @import("Compilation.zig");
+const Attribute = @import("Attribute.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const Header = @import("builtins/Properties.zig").Header;
+const Tree = @import("Tree.zig");
+const util = @import("util.zig");
+const is_windows = @import("builtin").os.tag == .windows;
+
+const Diagnostics = @This();
+
+const PointerSignMessage = " converts between pointers to integer types with different sign";
+
+pub const Message = struct {
+ tag: Tag,
+ kind: Kind = undefined,
+ loc: Source.Location = .{},
+ extra: Extra = .{ .none = {} },
+
+ pub const Extra = union {
+ str: []const u8,
+ tok_id: struct {
+ expected: Tree.Token.Id,
+ actual: Tree.Token.Id,
+ },
+ tok_id_expected: Tree.Token.Id,
+ arguments: struct {
+ expected: u32,
+ actual: u32,
+ },
+ codepoints: struct {
+ actual: u21,
+ resembles: u21,
+ },
+ attr_arg_count: struct {
+ attribute: Attribute.Tag,
+ expected: u32,
+ },
+ attr_arg_type: struct {
+ expected: Attribute.ArgumentType,
+ actual: Attribute.ArgumentType,
+ },
+ attr_enum: struct {
+ tag: Attribute.Tag,
+ },
+ ignored_record_attr: struct {
+ tag: Attribute.Tag,
+ specifier: enum { @"struct", @"union", @"enum" },
+ },
+ builtin_with_header: struct {
+ builtin: BuiltinFunction.Tag,
+ header: Header,
+ },
+ actual_codepoint: u21,
+ ascii: u7,
+ unsigned: u64,
+ pow_2_as_string: u8,
+ signed: i64,
+ none: void,
+ };
+};
+
+pub const Tag = std.meta.DeclEnum(messages);
+
+// u4 to avoid any possible packed struct issues
+pub const Kind = enum(u4) { @"fatal error", @"error", note, warning, off, default };
+
+pub const Options = packed struct {
+ // do not directly use these, instead add `const NAME = true;`
+ all: Kind = .default,
+ extra: Kind = .default,
+ pedantic: Kind = .default,
+
+ @"unsupported-pragma": Kind = .default,
+ @"c99-extensions": Kind = .default,
+ @"implicit-int": Kind = .default,
+ @"duplicate-decl-specifier": Kind = .default,
+ @"missing-declaration": Kind = .default,
+ @"extern-initializer": Kind = .default,
+ @"implicit-function-declaration": Kind = .default,
+ @"unused-value": Kind = .default,
+ @"unreachable-code": Kind = .default,
+ @"unknown-warning-option": Kind = .default,
+ @"gnu-empty-struct": Kind = .default,
+ @"gnu-alignof-expression": Kind = .default,
+ @"macro-redefined": Kind = .default,
+ @"generic-qual-type": Kind = .default,
+ multichar: Kind = .default,
+ @"pointer-integer-compare": Kind = .default,
+ @"compare-distinct-pointer-types": Kind = .default,
+ @"literal-conversion": Kind = .default,
+ @"cast-qualifiers": Kind = .default,
+ @"array-bounds": Kind = .default,
+ @"int-conversion": Kind = .default,
+ @"pointer-type-mismatch": Kind = .default,
+ @"c2x-extensions": Kind = .default,
+ @"incompatible-pointer-types": Kind = .default,
+ @"excess-initializers": Kind = .default,
+ @"division-by-zero": Kind = .default,
+ @"initializer-overrides": Kind = .default,
+ @"incompatible-pointer-types-discards-qualifiers": Kind = .default,
+ @"unknown-attributes": Kind = .default,
+ @"ignored-attributes": Kind = .default,
+ @"builtin-macro-redefined": Kind = .default,
+ @"gnu-label-as-value": Kind = .default,
+ @"malformed-warning-check": Kind = .default,
+ @"#pragma-messages": Kind = .default,
+ @"newline-eof": Kind = .default,
+ @"empty-translation-unit": Kind = .default,
+ @"implicitly-unsigned-literal": Kind = .default,
+ @"c99-compat": Kind = .default,
+ @"unicode-zero-width": Kind = .default,
+ @"unicode-homoglyph": Kind = .default,
+ @"return-type": Kind = .default,
+ @"dollar-in-identifier-extension": Kind = .default,
+ @"unknown-pragmas": Kind = .default,
+ @"predefined-identifier-outside-function": Kind = .default,
+ @"many-braces-around-scalar-init": Kind = .default,
+ uninitialized: Kind = .default,
+ @"gnu-statement-expression": Kind = .default,
+ @"gnu-imaginary-constant": Kind = .default,
+ @"gnu-complex-integer": Kind = .default,
+ @"ignored-qualifiers": Kind = .default,
+ @"integer-overflow": Kind = .default,
+ @"extra-semi": Kind = .default,
+ @"gnu-binary-literal": Kind = .default,
+ @"variadic-macros": Kind = .default,
+ varargs: Kind = .default,
+ @"#warnings": Kind = .default,
+ @"deprecated-declarations": Kind = .default,
+ @"backslash-newline-escape": Kind = .default,
+ @"pointer-to-int-cast": Kind = .default,
+ @"gnu-case-range": Kind = .default,
+ @"c++-compat": Kind = .default,
+ vla: Kind = .default,
+ @"float-overflow-conversion": Kind = .default,
+ @"float-zero-conversion": Kind = .default,
+ @"float-conversion": Kind = .default,
+ @"gnu-folding-constant": Kind = .default,
+ undef: Kind = .default,
+ @"ignored-pragmas": Kind = .default,
+ @"gnu-include-next": Kind = .default,
+ @"include-next-outside-header": Kind = .default,
+ @"include-next-absolute-path": Kind = .default,
+ @"enum-too-large": Kind = .default,
+ @"fixed-enum-extension": Kind = .default,
+ @"designated-init": Kind = .default,
+ @"attribute-warning": Kind = .default,
+ @"invalid-noreturn": Kind = .default,
+ @"zero-length-array": Kind = .default,
+ @"old-style-flexible-struct": Kind = .default,
+ @"gnu-zero-variadic-macro-arguments": Kind = .default,
+ @"main-return-type": Kind = .default,
+ @"expansion-to-defined": Kind = .default,
+ @"bit-int-extension": Kind = .default,
+ @"keyword-macro": Kind = .default,
+ @"pointer-arith": Kind = .default,
+ @"sizeof-array-argument": Kind = .default,
+ @"pre-c2x-compat": Kind = .default,
+ @"pointer-bool-conversion": Kind = .default,
+ @"string-conversion": Kind = .default,
+ @"gnu-auto-type": Kind = .default,
+ @"gnu-union-cast": Kind = .default,
+ @"pointer-sign": Kind = .default,
+ @"fuse-ld-path": Kind = .default,
+ @"language-extension-token": Kind = .default,
+ @"complex-component-init": Kind = .default,
+};
+
+const messages = struct {
+ pub const todo = struct { // Maybe someday this will no longer be needed.
+ const msg = "TODO: {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const error_directive = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const warning_directive = struct {
+ const msg = "{s}";
+ const opt = "#warnings";
+ const extra = .str;
+ const kind = .warning;
+ };
+ pub const elif_without_if = struct {
+ const msg = "#elif without #if";
+ const kind = .@"error";
+ };
+ pub const elif_after_else = struct {
+ const msg = "#elif after #else";
+ const kind = .@"error";
+ };
+ pub const elifdef_without_if = struct {
+ const msg = "#elifdef without #if";
+ const kind = .@"error";
+ };
+ pub const elifdef_after_else = struct {
+ const msg = "#elifdef after #else";
+ const kind = .@"error";
+ };
+ pub const elifndef_without_if = struct {
+ const msg = "#elifndef without #if";
+ const kind = .@"error";
+ };
+ pub const elifndef_after_else = struct {
+ const msg = "#elifndef after #else";
+ const kind = .@"error";
+ };
+ pub const else_without_if = struct {
+ const msg = "#else without #if";
+ const kind = .@"error";
+ };
+ pub const else_after_else = struct {
+ const msg = "#else after #else";
+ const kind = .@"error";
+ };
+ pub const endif_without_if = struct {
+ const msg = "#endif without #if";
+ const kind = .@"error";
+ };
+ pub const unknown_pragma = struct {
+ const msg = "unknown pragma ignored";
+ const opt = "unknown-pragmas";
+ const kind = .off;
+ const all = true;
+ };
+ pub const line_simple_digit = struct {
+ const msg = "#line directive requires a simple digit sequence";
+ const kind = .@"error";
+ };
+ pub const line_invalid_filename = struct {
+ const msg = "invalid filename for #line directive";
+ const kind = .@"error";
+ };
+ pub const unterminated_conditional_directive = struct {
+ const msg = "unterminated conditional directive";
+ const kind = .@"error";
+ };
+ pub const invalid_preprocessing_directive = struct {
+ const msg = "invalid preprocessing directive";
+ const kind = .@"error";
+ };
+ pub const macro_name_missing = struct {
+ const msg = "macro name missing";
+ const kind = .@"error";
+ };
+ pub const extra_tokens_directive_end = struct {
+ const msg = "extra tokens at end of macro directive";
+ const kind = .@"error";
+ };
+ pub const expected_value_in_expr = struct {
+ const msg = "expected value in expression";
+ const kind = .@"error";
+ };
+ pub const closing_paren = struct {
+ const msg = "expected closing ')'";
+ const kind = .@"error";
+ };
+ pub const to_match_paren = struct {
+ const msg = "to match this '('";
+ const kind = .note;
+ };
+ pub const to_match_brace = struct {
+ const msg = "to match this '{'";
+ const kind = .note;
+ };
+ pub const to_match_bracket = struct {
+ const msg = "to match this '['";
+ const kind = .note;
+ };
+ pub const header_str_closing = struct {
+ const msg = "expected closing '>'";
+ const kind = .@"error";
+ };
+ pub const header_str_match = struct {
+ const msg = "to match this '<'";
+ const kind = .note;
+ };
+ pub const string_literal_in_pp_expr = struct {
+ const msg = "string literal in preprocessor expression";
+ const kind = .@"error";
+ };
+ pub const float_literal_in_pp_expr = struct {
+ const msg = "floating point literal in preprocessor expression";
+ const kind = .@"error";
+ };
+ pub const defined_as_macro_name = struct {
+ const msg = "'defined' cannot be used as a macro name";
+ const kind = .@"error";
+ };
+ pub const macro_name_must_be_identifier = struct {
+ const msg = "macro name must be an identifier";
+ const kind = .@"error";
+ };
+ pub const whitespace_after_macro_name = struct {
+ const msg = "ISO C99 requires whitespace after the macro name";
+ const opt = "c99-extensions";
+ const kind = .warning;
+ };
+ pub const hash_hash_at_start = struct {
+ const msg = "'##' cannot appear at the start of a macro expansion";
+ const kind = .@"error";
+ };
+ pub const hash_hash_at_end = struct {
+ const msg = "'##' cannot appear at the end of a macro expansion";
+ const kind = .@"error";
+ };
+ pub const pasting_formed_invalid = struct {
+ const msg = "pasting formed '{s}', an invalid preprocessing token";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const missing_paren_param_list = struct {
+ const msg = "missing ')' in macro parameter list";
+ const kind = .@"error";
+ };
+ pub const unterminated_macro_param_list = struct {
+ const msg = "unterminated macro param list";
+ const kind = .@"error";
+ };
+ pub const invalid_token_param_list = struct {
+ const msg = "invalid token in macro parameter list";
+ const kind = .@"error";
+ };
+ pub const expected_comma_param_list = struct {
+ const msg = "expected comma in macro parameter list";
+ const kind = .@"error";
+ };
+ pub const hash_not_followed_param = struct {
+ const msg = "'#' is not followed by a macro parameter";
+ const kind = .@"error";
+ };
+ pub const expected_filename = struct {
+ const msg = "expected \"FILENAME\" or <FILENAME>";
+ const kind = .@"error";
+ };
+ pub const empty_filename = struct {
+ const msg = "empty filename";
+ const kind = .@"error";
+ };
+ pub const expected_invalid = struct {
+ const msg = "expected '{s}', found invalid bytes";
+ const extra = .tok_id_expected;
+ const kind = .@"error";
+ };
+ pub const expected_eof = struct {
+ const msg = "expected '{s}' before end of file";
+ const extra = .tok_id_expected;
+ const kind = .@"error";
+ };
+ pub const expected_token = struct {
+ const msg = "expected '{s}', found '{s}'";
+ const extra = .tok_id;
+ const kind = .@"error";
+ };
+ pub const expected_expr = struct {
+ const msg = "expected expression";
+ const kind = .@"error";
+ };
+ pub const expected_integer_constant_expr = struct {
+ const msg = "expression is not an integer constant expression";
+ const kind = .@"error";
+ };
+ pub const missing_type_specifier = struct {
+ const msg = "type specifier missing, defaults to 'int'";
+ const opt = "implicit-int";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const multiple_storage_class = struct {
+ const msg = "cannot combine with previous '{s}' declaration specifier";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const static_assert_failure = struct {
+ const msg = "static assertion failed";
+ const kind = .@"error";
+ };
+ pub const static_assert_failure_message = struct {
+ const msg = "static assertion failed {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const expected_type = struct {
+ const msg = "expected a type";
+ const kind = .@"error";
+ };
+ pub const cannot_combine_spec = struct {
+ const msg = "cannot combine with previous '{s}' specifier";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const duplicate_decl_spec = struct {
+ const msg = "duplicate '{s}' declaration specifier";
+ const extra = .str;
+ const opt = "duplicate-decl-specifier";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const restrict_non_pointer = struct {
+ const msg = "restrict requires a pointer or reference ('{s}' is invalid)";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const expected_external_decl = struct {
+ const msg = "expected external declaration";
+ const kind = .@"error";
+ };
+ pub const expected_ident_or_l_paren = struct {
+ const msg = "expected identifier or '('";
+ const kind = .@"error";
+ };
+ pub const missing_declaration = struct {
+ const msg = "declaration does not declare anything";
+ const opt = "missing-declaration";
+ const kind = .warning;
+ };
+ pub const func_not_in_root = struct {
+ const msg = "function definition is not allowed here";
+ const kind = .@"error";
+ };
+ pub const illegal_initializer = struct {
+ const msg = "illegal initializer (only variables can be initialized)";
+ const kind = .@"error";
+ };
+ pub const extern_initializer = struct {
+ const msg = "extern variable has initializer";
+ const opt = "extern-initializer";
+ const kind = .warning;
+ };
+ pub const spec_from_typedef = struct {
+ const msg = "'{s}' came from typedef";
+ const extra = .str;
+ const kind = .note;
+ };
+ pub const param_before_var_args = struct {
+ const msg = "ISO C requires a named parameter before '...'";
+ const kind = .@"error";
+ };
+ pub const void_only_param = struct {
+ const msg = "'void' must be the only parameter if specified";
+ const kind = .@"error";
+ };
+ pub const void_param_qualified = struct {
+ const msg = "'void' parameter cannot be qualified";
+ const kind = .@"error";
+ };
+ pub const void_must_be_first_param = struct {
+ const msg = "'void' must be the first parameter if specified";
+ const kind = .@"error";
+ };
+ pub const invalid_storage_on_param = struct {
+ const msg = "invalid storage class on function parameter";
+ const kind = .@"error";
+ };
+ pub const threadlocal_non_var = struct {
+ const msg = "_Thread_local only allowed on variables";
+ const kind = .@"error";
+ };
+ pub const func_spec_non_func = struct {
+ const msg = "'{s}' can only appear on functions";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const illegal_storage_on_func = struct {
+ const msg = "illegal storage class on function";
+ const kind = .@"error";
+ };
+ pub const illegal_storage_on_global = struct {
+ const msg = "illegal storage class on global variable";
+ const kind = .@"error";
+ };
+ pub const expected_stmt = struct {
+ const msg = "expected statement";
+ const kind = .@"error";
+ };
+ pub const func_cannot_return_func = struct {
+ const msg = "function cannot return a function";
+ const kind = .@"error";
+ };
+ pub const func_cannot_return_array = struct {
+ const msg = "function cannot return an array";
+ const kind = .@"error";
+ };
+ pub const undeclared_identifier = struct {
+ const msg = "use of undeclared identifier '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const not_callable = struct {
+ const msg = "cannot call non function type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const unsupported_str_cat = struct {
+ const msg = "unsupported string literal concatenation";
+ const kind = .@"error";
+ };
+ pub const static_func_not_global = struct {
+ const msg = "static functions must be global";
+ const kind = .@"error";
+ };
+ pub const implicit_func_decl = struct {
+ const msg = "implicit declaration of function '{s}' is invalid in C99";
+ const extra = .str;
+ const opt = "implicit-function-declaration";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const unknown_builtin = struct {
+ const msg = "use of unknown builtin '{s}'";
+ const extra = .str;
+ const opt = "implicit-function-declaration";
+ const kind = .@"error";
+ const all = true;
+ };
+ pub const implicit_builtin = struct {
+ const msg = "implicitly declaring library function '{s}'";
+ const extra = .str;
+ const opt = "implicit-function-declaration";
+ const kind = .@"error";
+ const all = true;
+ };
+ pub const implicit_builtin_header_note = struct {
+ const msg = "include the header <{s}.h> or explicitly provide a declaration for '{s}'";
+ const extra = .builtin_with_header;
+ const opt = "implicit-function-declaration";
+ const kind = .note;
+ const all = true;
+ };
+ pub const expected_param_decl = struct {
+ const msg = "expected parameter declaration";
+ const kind = .@"error";
+ };
+ pub const invalid_old_style_params = struct {
+ const msg = "identifier parameter lists are only allowed in function definitions";
+ const kind = .@"error";
+ };
+ pub const expected_fn_body = struct {
+ const msg = "expected function body after function declaration";
+ const kind = .@"error";
+ };
+ pub const invalid_void_param = struct {
+ const msg = "parameter cannot have void type";
+ const kind = .@"error";
+ };
+ pub const unused_value = struct {
+ const msg = "expression result unused";
+ const opt = "unused-value";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const continue_not_in_loop = struct {
+ const msg = "'continue' statement not in a loop";
+ const kind = .@"error";
+ };
+ pub const break_not_in_loop_or_switch = struct {
+ const msg = "'break' statement not in a loop or a switch";
+ const kind = .@"error";
+ };
+ pub const unreachable_code = struct {
+ const msg = "unreachable code";
+ const opt = "unreachable-code";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const duplicate_label = struct {
+ const msg = "duplicate label '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const previous_label = struct {
+ const msg = "previous definition of label '{s}' was here";
+ const extra = .str;
+ const kind = .note;
+ };
+ pub const undeclared_label = struct {
+ const msg = "use of undeclared label '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const case_not_in_switch = struct {
+ const msg = "'{s}' statement not in a switch statement";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const duplicate_switch_case_signed = struct {
+ const msg = "duplicate case value '{d}'";
+ const extra = .signed;
+ const kind = .@"error";
+ };
+ pub const duplicate_switch_case_unsigned = struct {
+ const msg = "duplicate case value '{d}'";
+ const extra = .unsigned;
+ const kind = .@"error";
+ };
+ pub const multiple_default = struct {
+ const msg = "multiple default cases in the same switch";
+ const kind = .@"error";
+ };
+ pub const previous_case = struct {
+ const msg = "previous case defined here";
+ const kind = .note;
+ };
+ pub const expected_arguments = struct {
+ const msg = "expected {d} argument(s) got {d}";
+ const extra = .arguments;
+ const kind = .@"error";
+ };
+ pub const expected_arguments_old = struct {
+ const msg = expected_arguments.msg;
+ const extra = .arguments;
+ const kind = .warning;
+ };
+ pub const expected_at_least_arguments = struct {
+ const msg = "expected at least {d} argument(s) got {d}";
+ const extra = .arguments;
+ const kind = .warning;
+ };
+ pub const invalid_static_star = struct {
+ const msg = "'static' may not be used with an unspecified variable length array size";
+ const kind = .@"error";
+ };
+ pub const static_non_param = struct {
+ const msg = "'static' used outside of function parameters";
+ const kind = .@"error";
+ };
+ pub const array_qualifiers = struct {
+ const msg = "type qualifier in non parameter array type";
+ const kind = .@"error";
+ };
+ pub const star_non_param = struct {
+ const msg = "star modifier used outside of function parameters";
+ const kind = .@"error";
+ };
+ pub const variable_len_array_file_scope = struct {
+ const msg = "variable length arrays not allowed at file scope";
+ const kind = .@"error";
+ };
+ pub const useless_static = struct {
+ const msg = "'static' useless without a constant size";
+ const kind = .warning;
+ const w_extra = true;
+ };
+ pub const negative_array_size = struct {
+ const msg = "array size must be 0 or greater";
+ const kind = .@"error";
+ };
+ pub const array_incomplete_elem = struct {
+ const msg = "array has incomplete element type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const array_func_elem = struct {
+ const msg = "arrays cannot have functions as their element type";
+ const kind = .@"error";
+ };
+ pub const static_non_outermost_array = struct {
+ const msg = "'static' used in non-outermost array type";
+ const kind = .@"error";
+ };
+ pub const qualifier_non_outermost_array = struct {
+ const msg = "type qualifier used in non-outermost array type";
+ const kind = .@"error";
+ };
+ pub const unterminated_macro_arg_list = struct {
+ const msg = "unterminated function macro argument list";
+ const kind = .@"error";
+ };
+ pub const unknown_warning = struct {
+ const msg = "unknown warning '{s}'";
+ const extra = .str;
+ const opt = "unknown-warning-option";
+ const kind = .warning;
+ };
+ pub const overflow_signed = struct {
+ const msg = "overflow in expression; result is '{d}'";
+ const extra = .signed;
+ const opt = "integer-overflow";
+ const kind = .warning;
+ };
+ pub const overflow_unsigned = struct {
+ const msg = overflow_signed.msg;
+ const extra = .unsigned;
+ const opt = "integer-overflow";
+ const kind = .warning;
+ };
+ pub const int_literal_too_big = struct {
+ const msg = "integer literal is too large to be represented in any integer type";
+ const kind = .@"error";
+ };
+ pub const indirection_ptr = struct {
+ const msg = "indirection requires pointer operand";
+ const kind = .@"error";
+ };
+ pub const addr_of_rvalue = struct {
+ const msg = "cannot take the address of an rvalue";
+ const kind = .@"error";
+ };
+ pub const addr_of_bitfield = struct {
+ const msg = "address of bit-field requested";
+ const kind = .@"error";
+ };
+ pub const not_assignable = struct {
+ const msg = "expression is not assignable";
+ const kind = .@"error";
+ };
+ pub const ident_or_l_brace = struct {
+ const msg = "expected identifier or '{'";
+ const kind = .@"error";
+ };
+ pub const empty_enum = struct {
+ const msg = "empty enum is invalid";
+ const kind = .@"error";
+ };
+ pub const redefinition = struct {
+ const msg = "redefinition of '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const previous_definition = struct {
+ const msg = "previous definition is here";
+ const kind = .note;
+ };
+ pub const expected_identifier = struct {
+ const msg = "expected identifier";
+ const kind = .@"error";
+ };
+ pub const expected_str_literal = struct {
+ const msg = "expected string literal for diagnostic message in static_assert";
+ const kind = .@"error";
+ };
+ pub const expected_str_literal_in = struct {
+ const msg = "expected string literal in '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const parameter_missing = struct {
+ const msg = "parameter named '{s}' is missing";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const empty_record = struct {
+ const msg = "empty {s} is a GNU extension";
+ const extra = .str;
+ const opt = "gnu-empty-struct";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const empty_record_size = struct {
+ const msg = "empty {s} has size 0 in C, size 1 in C++";
+ const extra = .str;
+ const opt = "c++-compat";
+ const kind = .off;
+ };
+ pub const wrong_tag = struct {
+ const msg = "use of '{s}' with tag type that does not match previous definition";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const expected_parens_around_typename = struct {
+ const msg = "expected parentheses around type name";
+ const kind = .@"error";
+ };
+ pub const alignof_expr = struct {
+ const msg = "'_Alignof' applied to an expression is a GNU extension";
+ const opt = "gnu-alignof-expression";
+ const kind = .warning;
+ const suppress_gnu = true;
+ };
+ pub const invalid_alignof = struct {
+ const msg = "invalid application of 'alignof' to an incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_sizeof = struct {
+ const msg = "invalid application of 'sizeof' to an incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const macro_redefined = struct {
+ const msg = "'{s}' macro redefined";
+ const extra = .str;
+ const opt = "macro-redefined";
+ const kind = .warning;
+ };
+ pub const generic_qual_type = struct {
+ const msg = "generic association with qualifiers cannot be matched with";
+ const opt = "generic-qual-type";
+ const kind = .warning;
+ };
+ pub const generic_array_type = struct {
+ const msg = "generic association array type cannot be matched with";
+ const opt = "generic-qual-type";
+ const kind = .warning;
+ };
+ pub const generic_func_type = struct {
+ const msg = "generic association function type cannot be matched with";
+ const opt = "generic-qual-type";
+ const kind = .warning;
+ };
+ pub const generic_duplicate = struct {
+ const msg = "type '{s}' in generic association compatible with previously specified type";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const generic_duplicate_here = struct {
+ const msg = "compatible type '{s}' specified here";
+ const extra = .str;
+ const kind = .note;
+ };
+ pub const generic_duplicate_default = struct {
+ const msg = "duplicate default generic association";
+ const kind = .@"error";
+ };
+ pub const generic_no_match = struct {
+ const msg = "controlling expression type '{s}' not compatible with any generic association type";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const escape_sequence_overflow = struct {
+ const msg = "escape sequence out of range";
+ const kind = .@"error";
+ };
+ pub const invalid_universal_character = struct {
+ const msg = "invalid universal character";
+ const kind = .@"error";
+ };
+ pub const multichar_literal = struct {
+ const msg = "multi-character character constant";
+ const opt = "multichar";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const unicode_multichar_literal = struct {
+ const msg = "Unicode character literals may not contain multiple characters";
+ const kind = .@"error";
+ };
+ pub const wide_multichar_literal = struct {
+ const msg = "extraneous characters in character constant ignored";
+ const kind = .warning;
+ };
+ pub const char_lit_too_wide = struct {
+ const msg = "character constant too long for its type";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const char_too_large = struct {
+ const msg = "character too large for enclosing character literal type";
+ const kind = .@"error";
+ };
+ pub const must_use_struct = struct {
+ const msg = "must use 'struct' tag to refer to type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const must_use_union = struct {
+ const msg = "must use 'union' tag to refer to type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const must_use_enum = struct {
+ const msg = "must use 'enum' tag to refer to type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const redefinition_different_sym = struct {
+ const msg = "redefinition of '{s}' as different kind of symbol";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const redefinition_incompatible = struct {
+ const msg = "redefinition of '{s}' with a different type";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const redefinition_of_parameter = struct {
+ const msg = "redefinition of parameter '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_bin_types = struct {
+ const msg = "invalid operands to binary expression ({s})";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const comparison_ptr_int = struct {
+ const msg = "comparison between pointer and integer ({s})";
+ const extra = .str;
+ const opt = "pointer-integer-compare";
+ const kind = .warning;
+ };
+ pub const comparison_distinct_ptr = struct {
+ const msg = "comparison of distinct pointer types ({s})";
+ const extra = .str;
+ const opt = "compare-distinct-pointer-types";
+ const kind = .warning;
+ };
+ pub const incompatible_pointers = struct {
+ const msg = "incompatible pointer types ({s})";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_argument_un = struct {
+ const msg = "invalid argument type '{s}' to unary expression";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const incompatible_assign = struct {
+ const msg = "assignment to {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const implicit_ptr_to_int = struct {
+ const msg = "implicit pointer to integer conversion from {s}";
+ const extra = .str;
+ const opt = "int-conversion";
+ const kind = .warning;
+ };
+ pub const invalid_cast_to_float = struct {
+ const msg = "pointer cannot be cast to type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_cast_to_pointer = struct {
+ const msg = "operand of type '{s}' cannot be cast to a pointer type";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_cast_type = struct {
+ const msg = "cannot cast to non arithmetic or pointer type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const qual_cast = struct {
+ const msg = "cast to type '{s}' will not preserve qualifiers";
+ const extra = .str;
+ const opt = "cast-qualifiers";
+ const kind = .warning;
+ };
+ pub const invalid_index = struct {
+ const msg = "array subscript is not an integer";
+ const kind = .@"error";
+ };
+ pub const invalid_subscript = struct {
+ const msg = "subscripted value is not an array or pointer";
+ const kind = .@"error";
+ };
+ pub const array_after = struct {
+ const msg = "array index {d} is past the end of the array";
+ const extra = .unsigned;
+ const opt = "array-bounds";
+ const kind = .warning;
+ };
+ pub const array_before = struct {
+ const msg = "array index {d} is before the beginning of the array";
+ const extra = .signed;
+ const opt = "array-bounds";
+ const kind = .warning;
+ };
+ pub const statement_int = struct {
+ const msg = "statement requires expression with integer type ('{s}' invalid)";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const statement_scalar = struct {
+ const msg = "statement requires expression with scalar type ('{s}' invalid)";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const func_should_return = struct {
+ const msg = "non-void function '{s}' should return a value";
+ const extra = .str;
+ const opt = "return-type";
+ const kind = .@"error";
+ const all = true;
+ };
+ pub const incompatible_return = struct {
+ const msg = "returning {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const incompatible_return_sign = struct {
+ const msg = "returning {s}" ++ PointerSignMessage;
+ const extra = .str;
+ const kind = .warning;
+ const opt = "pointer-sign";
+ };
+ pub const implicit_int_to_ptr = struct {
+ const msg = "implicit integer to pointer conversion from {s}";
+ const extra = .str;
+ const opt = "int-conversion";
+ const kind = .warning;
+ };
+ pub const func_does_not_return = struct {
+ const msg = "non-void function '{s}' does not return a value";
+ const extra = .str;
+ const opt = "return-type";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const void_func_returns_value = struct {
+ const msg = "void function '{s}' should not return a value";
+ const extra = .str;
+ const opt = "return-type";
+ const kind = .@"error";
+ const all = true;
+ };
+ pub const incompatible_arg = struct {
+ const msg = "passing {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const incompatible_ptr_arg = struct {
+ const msg = "passing {s}";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "incompatible-pointer-types";
+ };
+ pub const incompatible_ptr_arg_sign = struct {
+ const msg = "passing {s}" ++ PointerSignMessage;
+ const extra = .str;
+ const kind = .warning;
+ const opt = "pointer-sign";
+ };
+ pub const parameter_here = struct {
+ const msg = "passing argument to parameter here";
+ const kind = .note;
+ };
+ pub const atomic_array = struct {
+ const msg = "atomic cannot be applied to array type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const atomic_func = struct {
+ const msg = "atomic cannot be applied to function type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const atomic_incomplete = struct {
+ const msg = "atomic cannot be applied to incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const addr_of_register = struct {
+ const msg = "address of register variable requested";
+ const kind = .@"error";
+ };
+ pub const variable_incomplete_ty = struct {
+ const msg = "variable has incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const parameter_incomplete_ty = struct {
+ const msg = "parameter has incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const tentative_array = struct {
+ const msg = "tentative array definition assumed to have one element";
+ const kind = .warning;
+ };
+ pub const deref_incomplete_ty_ptr = struct {
+ const msg = "dereferencing pointer to incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const alignas_on_func = struct {
+ const msg = "'_Alignas' attribute only applies to variables and fields";
+ const kind = .@"error";
+ };
+ pub const alignas_on_param = struct {
+ const msg = "'_Alignas' attribute cannot be applied to a function parameter";
+ const kind = .@"error";
+ };
+ pub const minimum_alignment = struct {
+ const msg = "requested alignment is less than minimum alignment of {d}";
+ const extra = .unsigned;
+ const kind = .@"error";
+ };
+ pub const maximum_alignment = struct {
+ const msg = "requested alignment of {d} is too large";
+ const extra = .unsigned;
+ const kind = .@"error";
+ };
+ pub const negative_alignment = struct {
+ const msg = "requested negative alignment of {d} is invalid";
+ const extra = .signed;
+ const kind = .@"error";
+ };
+ pub const align_ignored = struct {
+ const msg = "'_Alignas' attribute is ignored here";
+ const kind = .warning;
+ };
+ pub const zero_align_ignored = struct {
+ const msg = "requested alignment of zero is ignored";
+ const kind = .warning;
+ };
+ pub const non_pow2_align = struct {
+ const msg = "requested alignment is not a power of 2";
+ const kind = .@"error";
+ };
+ pub const pointer_mismatch = struct {
+ const msg = "pointer type mismatch ({s})";
+ const extra = .str;
+ const opt = "pointer-type-mismatch";
+ const kind = .warning;
+ };
+ pub const static_assert_not_constant = struct {
+ const msg = "static_assert expression is not an integral constant expression";
+ const kind = .@"error";
+ };
+ pub const static_assert_missing_message = struct {
+ const msg = "static_assert with no message is a C2X extension";
+ const opt = "c2x-extensions";
+ const kind = .warning;
+ const suppress_version = .c2x;
+ };
+ pub const pre_c2x_compat = struct {
+ const msg = "{s} is incompatible with C standards before C2x";
+ const extra = .str;
+ const kind = .off;
+ const suppress_unless_version = .c2x;
+ const opt = "pre-c2x-compat";
+ };
+ pub const unbound_vla = struct {
+ const msg = "variable length array must be bound in function definition";
+ const kind = .@"error";
+ };
+ pub const array_too_large = struct {
+ const msg = "array is too large";
+ const kind = .@"error";
+ };
+ pub const incompatible_ptr_init = struct {
+ const msg = "incompatible pointer types initializing {s}";
+ const extra = .str;
+ const opt = "incompatible-pointer-types";
+ const kind = .warning;
+ };
+ pub const incompatible_ptr_init_sign = struct {
+ const msg = "incompatible pointer types initializing {s}" ++ PointerSignMessage;
+ const extra = .str;
+ const opt = "pointer-sign";
+ const kind = .warning;
+ };
+ pub const incompatible_ptr_assign = struct {
+ const msg = "incompatible pointer types assigning to {s}";
+ const extra = .str;
+ const opt = "incompatible-pointer-types";
+ const kind = .warning;
+ };
+ pub const incompatible_ptr_assign_sign = struct {
+ const msg = "incompatible pointer types assigning to {s} " ++ PointerSignMessage;
+ const extra = .str;
+ const opt = "pointer-sign";
+ const kind = .warning;
+ };
+ pub const vla_init = struct {
+ const msg = "variable-sized object may not be initialized";
+ const kind = .@"error";
+ };
+ pub const func_init = struct {
+ const msg = "illegal initializer type";
+ const kind = .@"error";
+ };
+ pub const incompatible_init = struct {
+ const msg = "initializing {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const empty_scalar_init = struct {
+ const msg = "scalar initializer cannot be empty";
+ const kind = .@"error";
+ };
+ pub const excess_scalar_init = struct {
+ const msg = "excess elements in scalar initializer";
+ const opt = "excess-initializers";
+ const kind = .warning;
+ };
+ pub const excess_str_init = struct {
+ const msg = "excess elements in string initializer";
+ const opt = "excess-initializers";
+ const kind = .warning;
+ };
+ pub const excess_struct_init = struct {
+ const msg = "excess elements in struct initializer";
+ const opt = "excess-initializers";
+ const kind = .warning;
+ };
+ pub const excess_array_init = struct {
+ const msg = "excess elements in array initializer";
+ const opt = "excess-initializers";
+ const kind = .warning;
+ };
+ pub const str_init_too_long = struct {
+ const msg = "initializer-string for char array is too long";
+ const opt = "excess-initializers";
+ const kind = .warning;
+ };
+ pub const arr_init_too_long = struct {
+ const msg = "cannot initialize type ({s})";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_typeof = struct {
+ const msg = "'{s} typeof' is invalid";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const division_by_zero = struct {
+ const msg = "{s} by zero is undefined";
+ const extra = .str;
+ const opt = "division-by-zero";
+ const kind = .warning;
+ };
+ pub const division_by_zero_macro = struct {
+ const msg = "{s} by zero in preprocessor expression";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const builtin_choose_cond = struct {
+ const msg = "'__builtin_choose_expr' requires a constant expression";
+ const kind = .@"error";
+ };
+ pub const alignas_unavailable = struct {
+ const msg = "'_Alignas' attribute requires integer constant expression";
+ const kind = .@"error";
+ };
+ pub const case_val_unavailable = struct {
+ const msg = "case value must be an integer constant expression";
+ const kind = .@"error";
+ };
+ pub const enum_val_unavailable = struct {
+ const msg = "enum value must be an integer constant expression";
+ const kind = .@"error";
+ };
+ pub const incompatible_array_init = struct {
+ const msg = "cannot initialize array of type {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const array_init_str = struct {
+ const msg = "array initializer must be an initializer list or wide string literal";
+ const kind = .@"error";
+ };
+ pub const initializer_overrides = struct {
+ const msg = "initializer overrides previous initialization";
+ const opt = "initializer-overrides";
+ const kind = .warning;
+ const w_extra = true;
+ };
+ pub const previous_initializer = struct {
+ const msg = "previous initialization";
+ const kind = .note;
+ };
+ pub const invalid_array_designator = struct {
+ const msg = "array designator used for non-array type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const negative_array_designator = struct {
+ const msg = "array designator value {d} is negative";
+ const extra = .signed;
+ const kind = .@"error";
+ };
+ pub const oob_array_designator = struct {
+ const msg = "array designator index {d} exceeds array bounds";
+ const extra = .unsigned;
+ const kind = .@"error";
+ };
+ pub const invalid_field_designator = struct {
+ const msg = "field designator used for non-record type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const no_such_field_designator = struct {
+ const msg = "record type has no field named '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const empty_aggregate_init_braces = struct {
+ const msg = "initializer for aggregate with no elements requires explicit braces";
+ const kind = .@"error";
+ };
+ pub const ptr_init_discards_quals = struct {
+ const msg = "initializing {s} discards qualifiers";
+ const extra = .str;
+ const opt = "incompatible-pointer-types-discards-qualifiers";
+ const kind = .warning;
+ };
+ pub const ptr_assign_discards_quals = struct {
+ const msg = "assigning to {s} discards qualifiers";
+ const extra = .str;
+ const opt = "incompatible-pointer-types-discards-qualifiers";
+ const kind = .warning;
+ };
+ pub const ptr_ret_discards_quals = struct {
+ const msg = "returning {s} discards qualifiers";
+ const extra = .str;
+ const opt = "incompatible-pointer-types-discards-qualifiers";
+ const kind = .warning;
+ };
+ pub const ptr_arg_discards_quals = struct {
+ const msg = "passing {s} discards qualifiers";
+ const extra = .str;
+ const opt = "incompatible-pointer-types-discards-qualifiers";
+ const kind = .warning;
+ };
+ pub const unknown_attribute = struct {
+ const msg = "unknown attribute '{s}' ignored";
+ const extra = .str;
+ const opt = "unknown-attributes";
+ const kind = .warning;
+ };
+ pub const ignored_attribute = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const invalid_fallthrough = struct {
+ const msg = "fallthrough annotation does not directly precede switch label";
+ const kind = .@"error";
+ };
+ pub const cannot_apply_attribute_to_statement = struct {
+ const msg = "'{s}' attribute cannot be applied to a statement";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const builtin_macro_redefined = struct {
+ const msg = "redefining builtin macro";
+ const opt = "builtin-macro-redefined";
+ const kind = .warning;
+ };
+ pub const feature_check_requires_identifier = struct {
+ const msg = "builtin feature check macro requires a parenthesized identifier";
+ const kind = .@"error";
+ };
+ pub const missing_tok_builtin = struct {
+ const msg = "missing '{s}', after builtin feature-check macro";
+ const extra = .tok_id_expected;
+ const kind = .@"error";
+ };
+ pub const gnu_label_as_value = struct {
+ const msg = "use of GNU address-of-label extension";
+ const opt = "gnu-label-as-value";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const expected_record_ty = struct {
+ const msg = "member reference base type '{s}' is not a structure or union";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const member_expr_not_ptr = struct {
+ const msg = "member reference type '{s}' is not a pointer; did you mean to use '.'?";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const member_expr_ptr = struct {
+ const msg = "member reference type '{s}' is a pointer; did you mean to use '->'?";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const no_such_member = struct {
+ const msg = "no member named {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const malformed_warning_check = struct {
+ const msg = "{s} expected option name (e.g. \"-Wundef\")";
+ const extra = .str;
+ const opt = "malformed-warning-check";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const invalid_computed_goto = struct {
+ const msg = "computed goto in function with no address-of-label expressions";
+ const kind = .@"error";
+ };
+ pub const pragma_warning_message = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const opt = "#pragma-messages";
+ const kind = .warning;
+ };
+ pub const pragma_error_message = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const pragma_message = struct {
+ const msg = "#pragma message: {s}";
+ const extra = .str;
+ const kind = .note;
+ };
+ pub const pragma_requires_string_literal = struct {
+ const msg = "pragma {s} requires string literal";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const poisoned_identifier = struct {
+ const msg = "attempt to use a poisoned identifier";
+ const kind = .@"error";
+ };
+ pub const pragma_poison_identifier = struct {
+ const msg = "can only poison identifier tokens";
+ const kind = .@"error";
+ };
+ pub const pragma_poison_macro = struct {
+ const msg = "poisoning existing macro";
+ const kind = .warning;
+ };
+ pub const newline_eof = struct {
+ const msg = "no newline at end of file";
+ const opt = "newline-eof";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const empty_translation_unit = struct {
+ const msg = "ISO C requires a translation unit to contain at least one declaration";
+ const opt = "empty-translation-unit";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const omitting_parameter_name = struct {
+ const msg = "omitting the parameter name in a function definition is a C2x extension";
+ const opt = "c2x-extensions";
+ const kind = .warning;
+ const suppress_version = .c2x;
+ };
+ pub const non_int_bitfield = struct {
+ const msg = "bit-field has non-integer type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const negative_bitwidth = struct {
+ const msg = "bit-field has negative width ({d})";
+ const extra = .signed;
+ const kind = .@"error";
+ };
+ pub const zero_width_named_field = struct {
+ const msg = "named bit-field has zero width";
+ const kind = .@"error";
+ };
+ pub const bitfield_too_big = struct {
+ const msg = "width of bit-field exceeds width of its type";
+ const kind = .@"error";
+ };
+ pub const invalid_utf8 = struct {
+ const msg = "source file is not valid UTF-8";
+ const kind = .@"error";
+ };
+ pub const implicitly_unsigned_literal = struct {
+ const msg = "integer literal is too large to be represented in a signed integer type, interpreting as unsigned";
+ const opt = "implicitly-unsigned-literal";
+ const kind = .warning;
+ };
+ pub const invalid_preproc_operator = struct {
+ const msg = "token is not a valid binary operator in a preprocessor subexpression";
+ const kind = .@"error";
+ };
+ pub const invalid_preproc_expr_start = struct {
+ const msg = "invalid token at start of a preprocessor expression";
+ const kind = .@"error";
+ };
+ pub const c99_compat = struct {
+ const msg = "using this character in an identifier is incompatible with C99";
+ const opt = "c99-compat";
+ const kind = .off;
+ };
+ pub const unicode_zero_width = struct {
+ const msg = "identifier contains Unicode character <U+{X:0>4}> that is invisible in some environments";
+ const opt = "unicode-homoglyph";
+ const extra = .actual_codepoint;
+ const kind = .warning;
+ };
+ pub const unicode_homoglyph = struct {
+ const msg = "treating Unicode character <U+{X:0>4}> as identifier character rather than as '{u}' symbol";
+ const extra = .codepoints;
+ const opt = "unicode-homoglyph";
+ const kind = .warning;
+ };
+ pub const meaningless_asm_qual = struct {
+ const msg = "meaningless '{s}' on assembly outside function";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const duplicate_asm_qual = struct {
+ const msg = "duplicate asm qualifier '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_asm_str = struct {
+ const msg = "cannot use {s} string literal in assembly";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const dollar_in_identifier_extension = struct {
+ const msg = "'$' in identifier";
+ const opt = "dollar-in-identifier-extension";
+ const kind = .off;
+ const suppress_language_option = "dollars_in_identifiers";
+ const pedantic = true;
+ };
+ pub const dollars_in_identifiers = struct {
+ const msg = "illegal character '$' in identifier";
+ const kind = .@"error";
+ };
+ pub const expanded_from_here = struct {
+ const msg = "expanded from here";
+ const kind = .note;
+ };
+ pub const skipping_macro_backtrace = struct {
+ const msg = "(skipping {d} expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)";
+ const extra = .unsigned;
+ const kind = .note;
+ };
+ pub const pragma_operator_string_literal = struct {
+ const msg = "_Pragma requires exactly one string literal token";
+ const kind = .@"error";
+ };
+ pub const unknown_gcc_pragma = struct {
+ const msg = "pragma GCC expected 'error', 'warning', 'diagnostic', 'poison'";
+ const opt = "unknown-pragmas";
+ const kind = .off;
+ const all = true;
+ };
+ pub const unknown_gcc_pragma_directive = struct {
+ const msg = "pragma GCC diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'";
+ const opt = "unknown-pragmas";
+ const kind = .warning;
+ const all = true;
+ };
+ pub const predefined_top_level = struct {
+ const msg = "predefined identifier is only valid inside function";
+ const opt = "predefined-identifier-outside-function";
+ const kind = .warning;
+ };
+ pub const incompatible_va_arg = struct {
+ const msg = "first argument to va_arg, is of type '{s}' and not 'va_list'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const too_many_scalar_init_braces = struct {
+ const msg = "too many braces around scalar initializer";
+ const opt = "many-braces-around-scalar-init";
+ const kind = .warning;
+ };
+ pub const uninitialized_in_own_init = struct {
+ const msg = "variable '{s}' is uninitialized when used within its own initialization";
+ const extra = .str;
+ const opt = "uninitialized";
+ const kind = .off;
+ const all = true;
+ };
+ pub const gnu_statement_expression = struct {
+ const msg = "use of GNU statement expression extension";
+ const opt = "gnu-statement-expression";
+ const kind = .off;
+ const suppress_gnu = true;
+ const pedantic = true;
+ };
+ pub const stmt_expr_not_allowed_file_scope = struct {
+ const msg = "statement expression not allowed at file scope";
+ const kind = .@"error";
+ };
+ pub const gnu_imaginary_constant = struct {
+ const msg = "imaginary constants are a GNU extension";
+ const opt = "gnu-imaginary-constant";
+ const kind = .off;
+ const suppress_gnu = true;
+ const pedantic = true;
+ };
+ pub const plain_complex = struct {
+ const msg = "plain '_Complex' requires a type specifier; assuming '_Complex double'";
+ const kind = .warning;
+ };
+ pub const complex_int = struct {
+ const msg = "complex integer types are a GNU extension";
+ const opt = "gnu-complex-integer";
+ const suppress_gnu = true;
+ const kind = .off;
+ };
+ pub const qual_on_ret_type = struct {
+ const msg = "'{s}' type qualifier on return type has no effect";
+ const opt = "ignored-qualifiers";
+ const extra = .str;
+ const kind = .off;
+ const all = true;
+ };
+ pub const cli_invalid_standard = struct {
+ const msg = "invalid standard '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const cli_invalid_target = struct {
+ const msg = "invalid target '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const cli_invalid_emulate = struct {
+ const msg = "invalid compiler '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const cli_unknown_arg = struct {
+ const msg = "unknown argument '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const cli_error = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const cli_unused_link_object = struct {
+ const msg = "{s}: linker input file unused because linking not done";
+ const extra = .str;
+ const kind = .warning;
+ };
+ pub const cli_unknown_linker = struct {
+ const msg = "unrecognized linker '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const extra_semi = struct {
+ const msg = "extra ';' outside of a function";
+ const opt = "extra-semi";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const func_field = struct {
+ const msg = "field declared as a function";
+ const kind = .@"error";
+ };
+ pub const vla_field = struct {
+ const msg = "variable length array fields extension is not supported";
+ const kind = .@"error";
+ };
+ pub const field_incomplete_ty = struct {
+ const msg = "field has incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const flexible_in_union = struct {
+ const msg = "flexible array member in union is not allowed";
+ const kind = .@"error";
+ const suppress_msvc = true;
+ };
+ pub const flexible_non_final = struct {
+ const msg = "flexible array member is not at the end of struct";
+ const kind = .@"error";
+ };
+ pub const flexible_in_empty = struct {
+ const msg = "flexible array member in otherwise empty struct";
+ const kind = .@"error";
+ const suppress_msvc = true;
+ };
+ pub const duplicate_member = struct {
+ const msg = "duplicate member '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const binary_integer_literal = struct {
+ const msg = "binary integer literals are a GNU extension";
+ const kind = .off;
+ const opt = "gnu-binary-literal";
+ const pedantic = true;
+ };
+ pub const gnu_va_macro = struct {
+ const msg = "named variadic macros are a GNU extension";
+ const opt = "variadic-macros";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const builtin_must_be_called = struct {
+ const msg = "builtin function must be directly called";
+ const kind = .@"error";
+ };
+ pub const va_start_not_in_func = struct {
+ const msg = "'va_start' cannot be used outside a function";
+ const kind = .@"error";
+ };
+ pub const va_start_fixed_args = struct {
+ const msg = "'va_start' used in a function with fixed args";
+ const kind = .@"error";
+ };
+ pub const va_start_not_last_param = struct {
+ const msg = "second argument to 'va_start' is not the last named parameter";
+ const opt = "varargs";
+ const kind = .warning;
+ };
+ pub const attribute_not_enough_args = struct {
+ const msg = "'{s}' attribute takes at least {d} argument(s)";
+ const kind = .@"error";
+ const extra = .attr_arg_count;
+ };
+ pub const attribute_too_many_args = struct {
+ const msg = "'{s}' attribute takes at most {d} argument(s)";
+ const kind = .@"error";
+ const extra = .attr_arg_count;
+ };
+ pub const attribute_arg_invalid = struct {
+ const msg = "Attribute argument is invalid, expected {s} but got {s}";
+ const kind = .@"error";
+ const extra = .attr_arg_type;
+ };
+ pub const unknown_attr_enum = struct {
+ const msg = "Unknown `{s}` argument. Possible values are: {s}";
+ const kind = .@"error";
+ const extra = .attr_enum;
+ };
+ pub const attribute_requires_identifier = struct {
+ const msg = "'{s}' attribute requires an identifier";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const declspec_not_enabled = struct {
+ const msg = "'__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes";
+ const kind = .@"error";
+ };
+ pub const declspec_attr_not_supported = struct {
+ const msg = "__declspec attribute '{s}' is not supported";
+ const extra = .str;
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const deprecated_declarations = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const opt = "deprecated-declarations";
+ const kind = .warning;
+ };
+ pub const deprecated_note = struct {
+ const msg = "'{s}' has been explicitly marked deprecated here";
+ const extra = .str;
+ const opt = "deprecated-declarations";
+ const kind = .note;
+ };
+ pub const unavailable = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const unavailable_note = struct {
+ const msg = "'{s}' has been explicitly marked unavailable here";
+ const extra = .str;
+ const kind = .note;
+ };
+ pub const warning_attribute = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "attribute-warning";
+ };
+ pub const error_attribute = struct {
+ const msg = "{s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const ignored_record_attr = struct {
+ const msg = "attribute '{s}' is ignored, place it after \"{s}\" to apply attribute to type declaration";
+ const extra = .ignored_record_attr;
+ const kind = .warning;
+ const opt = "ignored-attributes";
+ };
+ pub const backslash_newline_escape = struct {
+ const msg = "backslash and newline separated by space";
+ const kind = .warning;
+ const opt = "backslash-newline-escape";
+ };
+ pub const array_size_non_int = struct {
+ const msg = "size of array has non-integer type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const cast_to_smaller_int = struct {
+ const msg = "cast to smaller integer type {s}";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "pointer-to-int-cast";
+ };
+ pub const gnu_switch_range = struct {
+ const msg = "use of GNU case range extension";
+ const opt = "gnu-case-range";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const empty_case_range = struct {
+ const msg = "empty case range specified";
+ const kind = .warning;
+ };
+ pub const non_standard_escape_char = struct {
+ const msg = "use of non-standard escape character '\\e'";
+ const kind = .off;
+ const opt = "pedantic";
+ };
+ pub const invalid_pp_stringify_escape = struct {
+ const msg = "invalid string literal, ignoring final '\\'";
+ const kind = .warning;
+ };
+ pub const vla = struct {
+ const msg = "variable length array used";
+ const kind = .off;
+ const opt = "vla";
+ };
+ pub const float_overflow_conversion = struct {
+ const msg = "implicit conversion of non-finite value from {s} is undefined";
+ const extra = .str;
+ const kind = .off;
+ const opt = "float-overflow-conversion";
+ };
+ pub const float_out_of_range = struct {
+ const msg = "implicit conversion of out of range value from {s} is undefined";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "literal-conversion";
+ };
+ pub const float_zero_conversion = struct {
+ const msg = "implicit conversion from {s}";
+ const extra = .str;
+ const kind = .off;
+ const opt = "float-zero-conversion";
+ };
+ pub const float_value_changed = struct {
+ const msg = "implicit conversion from {s}";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "float-conversion";
+ };
+ pub const float_to_int = struct {
+ const msg = "implicit conversion turns floating-point number into integer: {s}";
+ const extra = .str;
+ const kind = .off;
+ const opt = "literal-conversion";
+ };
+ pub const const_decl_folded = struct {
+ const msg = "expression is not an integer constant expression; folding it to a constant is a GNU extension";
+ const kind = .off;
+ const opt = "gnu-folding-constant";
+ const pedantic = true;
+ };
+ pub const const_decl_folded_vla = struct {
+ const msg = "variable length array folded to constant array as an extension";
+ const kind = .off;
+ const opt = "gnu-folding-constant";
+ const pedantic = true;
+ };
+ pub const redefinition_of_typedef = struct {
+ const msg = "typedef redefinition with different types ({s})";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const undefined_macro = struct {
+ const msg = "'{s}' is not defined, evaluates to 0";
+ const extra = .str;
+ const kind = .off;
+ const opt = "undef";
+ };
+ pub const fn_macro_undefined = struct {
+ const msg = "function-like macro '{s}' is not defined";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const preprocessing_directive_only = struct {
+ const msg = "'{s}' must be used within a preprocessing directive";
+ const extra = .tok_id_expected;
+ const kind = .@"error";
+ };
+ pub const missing_lparen_after_builtin = struct {
+ const msg = "Missing '(' after built-in macro '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const offsetof_ty = struct {
+ const msg = "offsetof requires struct or union type, '{s}' invalid";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const offsetof_incomplete = struct {
+ const msg = "offsetof of incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const offsetof_array = struct {
+ const msg = "offsetof requires array type, '{s}' invalid";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const pragma_pack_lparen = struct {
+ const msg = "missing '(' after '#pragma pack' - ignoring";
+ const kind = .warning;
+ const opt = "ignored-pragmas";
+ };
+ pub const pragma_pack_rparen = struct {
+ const msg = "missing ')' after '#pragma pack' - ignoring";
+ const kind = .warning;
+ const opt = "ignored-pragmas";
+ };
+ pub const pragma_pack_unknown_action = struct {
+ const msg = "unknown action for '#pragma pack' - ignoring";
+ const opt = "ignored-pragmas";
+ const kind = .warning;
+ };
+ pub const pragma_pack_show = struct {
+ const msg = "value of #pragma pack(show) == {d}";
+ const extra = .unsigned;
+ const kind = .warning;
+ };
+ pub const pragma_pack_int = struct {
+ const msg = "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'";
+ const opt = "ignored-pragmas";
+ const kind = .warning;
+ };
+ pub const pragma_pack_int_ident = struct {
+ const msg = "expected integer or identifier in '#pragma pack' - ignored";
+ const opt = "ignored-pragmas";
+ const kind = .warning;
+ };
+ pub const pragma_pack_undefined_pop = struct {
+ const msg = "specifying both a name and alignment to 'pop' is undefined";
+ const kind = .warning;
+ };
+ pub const pragma_pack_empty_stack = struct {
+ const msg = "#pragma pack(pop, ...) failed: stack empty";
+ const opt = "ignored-pragmas";
+ const kind = .warning;
+ };
+ pub const cond_expr_type = struct {
+ const msg = "used type '{s}' where arithmetic or pointer type is required";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const too_many_includes = struct {
+ const msg = "#include nested too deeply";
+ const kind = .@"error";
+ };
+ pub const enumerator_too_small = struct {
+ const msg = "ISO C restricts enumerator values to range of 'int' ({d} is too small)";
+ const extra = .signed;
+ const kind = .off;
+ const opt = "pedantic";
+ };
+ pub const enumerator_too_large = struct {
+ const msg = "ISO C restricts enumerator values to range of 'int' ({d} is too large)";
+ const extra = .unsigned;
+ const kind = .off;
+ const opt = "pedantic";
+ };
+ pub const include_next = struct {
+ const msg = "#include_next is a language extension";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "gnu-include-next";
+ };
+ pub const include_next_outside_header = struct {
+ const msg = "#include_next in primary source file; will search from start of include path";
+ const kind = .warning;
+ const opt = "include-next-outside-header";
+ };
+ pub const enumerator_overflow = struct {
+ const msg = "overflow in enumeration value";
+ const kind = .warning;
+ };
+ pub const enum_not_representable = struct {
+ const msg = "incremented enumerator value {s} is not representable in the largest integer type";
+ const kind = .warning;
+ const opt = "enum-too-large";
+ const extra = .pow_2_as_string;
+ };
+ pub const enum_too_large = struct {
+ const msg = "enumeration values exceed range of largest integer";
+ const kind = .warning;
+ const opt = "enum-too-large";
+ };
+ pub const enum_fixed = struct {
+ const msg = "enumeration types with a fixed underlying type are a Clang extension";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "fixed-enum-extension";
+ };
+ pub const enum_prev_nonfixed = struct {
+ const msg = "enumeration previously declared with nonfixed underlying type";
+ const kind = .@"error";
+ };
+ pub const enum_prev_fixed = struct {
+ const msg = "enumeration previously declared with fixed underlying type";
+ const kind = .@"error";
+ };
+ pub const enum_different_explicit_ty = struct {
+ // str will be like 'new' (was 'old'
+ const msg = "enumeration redeclared with different underlying type {s})";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const enum_not_representable_fixed = struct {
+ const msg = "enumerator value is not representable in the underlying type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const transparent_union_wrong_type = struct {
+ const msg = "'transparent_union' attribute only applies to unions";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const transparent_union_one_field = struct {
+ const msg = "transparent union definition must contain at least one field; transparent_union attribute ignored";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const transparent_union_size = struct {
+ const msg = "size of field {s} bits) does not match the size of the first field in transparent union; transparent_union attribute ignored";
+ const extra = .str;
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const transparent_union_size_note = struct {
+ const msg = "size of first field is {d}";
+ const extra = .unsigned;
+ const kind = .note;
+ };
+ pub const designated_init_invalid = struct {
+ const msg = "'designated_init' attribute is only valid on 'struct' type'";
+ const kind = .@"error";
+ };
+ pub const designated_init_needed = struct {
+ const msg = "positional initialization of field in 'struct' declared with 'designated_init' attribute";
+ const opt = "designated-init";
+ const kind = .warning;
+ };
+ pub const ignore_common = struct {
+ const msg = "ignoring attribute 'common' because it conflicts with attribute 'nocommon'";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const ignore_nocommon = struct {
+ const msg = "ignoring attribute 'nocommon' because it conflicts with attribute 'common'";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const non_string_ignored = struct {
+ const msg = "'nonstring' attribute ignored on objects of type '{s}'";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const local_variable_attribute = struct {
+ const msg = "'{s}' attribute only applies to local variables";
+ const extra = .str;
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const ignore_cold = struct {
+ const msg = "ignoring attribute 'cold' because it conflicts with attribute 'hot'";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const ignore_hot = struct {
+ const msg = "ignoring attribute 'hot' because it conflicts with attribute 'cold'";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const ignore_noinline = struct {
+ const msg = "ignoring attribute 'noinline' because it conflicts with attribute 'always_inline'";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const ignore_always_inline = struct {
+ const msg = "ignoring attribute 'always_inline' because it conflicts with attribute 'noinline'";
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const invalid_noreturn = struct {
+ const msg = "function '{s}' declared 'noreturn' should not return";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "invalid-noreturn";
+ };
+ pub const nodiscard_unused = struct {
+ const msg = "ignoring return value of '{s}', declared with 'nodiscard' attribute";
+ const extra = .str;
+ const kind = .warning;
+ const op = "unused-result";
+ };
+ pub const warn_unused_result = struct {
+ const msg = "ignoring return value of '{s}', declared with 'warn_unused_result' attribute";
+ const extra = .str;
+ const kind = .warning;
+ const op = "unused-result";
+ };
+ pub const invalid_vec_elem_ty = struct {
+ const msg = "invalid vector element type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const vec_size_not_multiple = struct {
+ const msg = "vector size not an integral multiple of component size";
+ const kind = .@"error";
+ };
+ pub const invalid_imag = struct {
+ const msg = "invalid type '{s}' to __imag operator";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_real = struct {
+ const msg = "invalid type '{s}' to __real operator";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const zero_length_array = struct {
+ const msg = "zero size arrays are an extension";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "zero-length-array";
+ };
+ pub const old_style_flexible_struct = struct {
+ const msg = "array index {d} is past the end of the array";
+ const extra = .unsigned;
+ const kind = .off;
+ const pedantic = true;
+ const opt = "old-style-flexible-struct";
+ };
+ pub const comma_deletion_va_args = struct {
+ const msg = "token pasting of ',' and __VA_ARGS__ is a GNU extension";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "gnu-zero-variadic-macro-arguments";
+ const suppress_gcc = true;
+ };
+ pub const main_return_type = struct {
+ const msg = "return type of 'main' is not 'int'";
+ const kind = .warning;
+ const opt = "main-return-type";
+ };
+ pub const expansion_to_defined = struct {
+ const msg = "macro expansion producing 'defined' has undefined behavior";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "expansion-to-defined";
+ };
+ pub const invalid_int_suffix = struct {
+ const msg = "invalid suffix '{s}' on integer constant";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_float_suffix = struct {
+ const msg = "invalid suffix '{s}' on floating constant";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const invalid_octal_digit = struct {
+ const msg = "invalid digit '{c}' in octal constant";
+ const extra = .ascii;
+ const kind = .@"error";
+ };
+ pub const invalid_binary_digit = struct {
+ const msg = "invalid digit '{c}' in binary constant";
+ const extra = .ascii;
+ const kind = .@"error";
+ };
+ pub const exponent_has_no_digits = struct {
+ const msg = "exponent has no digits";
+ const kind = .@"error";
+ };
+ pub const hex_floating_constant_requires_exponent = struct {
+ const msg = "hexadecimal floating constant requires an exponent";
+ const kind = .@"error";
+ };
+ pub const sizeof_returns_zero = struct {
+ const msg = "sizeof returns 0";
+ const kind = .warning;
+ const suppress_gcc = true;
+ const suppress_clang = true;
+ };
+ pub const declspec_not_allowed_after_declarator = struct {
+ const msg = "'declspec' attribute not allowed after declarator";
+ const kind = .@"error";
+ };
+ pub const declarator_name_tok = struct {
+ const msg = "this declarator";
+ const kind = .note;
+ };
+ pub const type_not_supported_on_target = struct {
+ const msg = "{s} is not supported on this target";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const bit_int = struct {
+ const msg = "'_BitInt' in C17 and earlier is a Clang extension'";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "bit-int-extension";
+ const suppress_version = .c2x;
+ };
+ pub const unsigned_bit_int_too_small = struct {
+ const msg = "{s} must have a bit size of at least 1";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const signed_bit_int_too_small = struct {
+ const msg = "{s} must have a bit size of at least 2";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const bit_int_too_big = struct {
+ const msg = "{s} of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Compilation.bit_int_max_bits}) ++ " not supported";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const keyword_macro = struct {
+ const msg = "keyword is hidden by macro definition";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "keyword-macro";
+ };
+ pub const ptr_arithmetic_incomplete = struct {
+ const msg = "arithmetic on a pointer to an incomplete type '{s}'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const callconv_not_supported = struct {
+ const msg = "'{s}' calling convention is not supported for this target";
+ const extra = .str;
+ const opt = "ignored-attributes";
+ const kind = .warning;
+ };
+ pub const pointer_arith_void = struct {
+ const msg = "invalid application of '{s}' to a void type";
+ const extra = .str;
+ const kind = .off;
+ const pedantic = true;
+ const opt = "pointer-arith";
+ };
+ pub const sizeof_array_arg = struct {
+ const msg = "sizeof on array function parameter will return size of {s}";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "sizeof-array-argument";
+ };
+ pub const array_address_to_bool = struct {
+ const msg = "address of array '{s}' will always evaluate to 'true'";
+ const extra = .str;
+ const kind = .warning;
+ const opt = "pointer-bool-conversion";
+ };
+ pub const string_literal_to_bool = struct {
+ const msg = "implicit conversion turns string literal into bool: {s}";
+ const extra = .str;
+ const kind = .off;
+ const opt = "string-conversion";
+ };
+ pub const constant_expression_conversion_not_allowed = struct {
+ const msg = "this conversion is not allowed in a constant expression";
+ const kind = .note;
+ };
+ pub const invalid_object_cast = struct {
+ const msg = "cannot cast an object of type {s}";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const cli_invalid_fp_eval_method = struct {
+ const msg = "unsupported argument '{s}' to option '-ffp-eval-method='; expected 'source', 'double', or 'extended'";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const suggest_pointer_for_invalid_fp16 = struct {
+ const msg = "{s} cannot have __fp16 type; did you forget * ?";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const bitint_suffix = struct {
+ const msg = "'_BitInt' suffix for literals is a C2x extension";
+ const opt = "c2x-extensions";
+ const kind = .warning;
+ const suppress_version = .c2x;
+ };
+ pub const auto_type_extension = struct {
+ const msg = "'__auto_type' is a GNU extension";
+ const opt = "gnu-auto-type";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const auto_type_not_allowed = struct {
+ const msg = "'__auto_type' not allowed in {s}";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const auto_type_requires_initializer = struct {
+ const msg = "declaration of variable '{s}' with deduced type requires an initializer";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const auto_type_requires_single_declarator = struct {
+ const msg = "'__auto_type' may only be used with a single declarator";
+ const kind = .@"error";
+ };
+ pub const auto_type_requires_plain_declarator = struct {
+ const msg = "'__auto_type' requires a plain identifier as declarator";
+ const kind = .@"error";
+ };
+ pub const invalid_cast_to_auto_type = struct {
+ const msg = "invalid cast to '__auto_type'";
+ const kind = .@"error";
+ };
+ pub const auto_type_from_bitfield = struct {
+ const msg = "cannot use bit-field as '__auto_type' initializer";
+ const kind = .@"error";
+ };
+ pub const array_of_auto_type = struct {
+ const msg = "'{s}' declared as array of '__auto_type'";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const auto_type_with_init_list = struct {
+ const msg = "cannot use '__auto_type' with initializer list";
+ const kind = .@"error";
+ };
+ pub const missing_semicolon = struct {
+ const msg = "expected ';' at end of declaration list";
+ const kind = .warning;
+ };
+ pub const tentative_definition_incomplete = struct {
+ const msg = "tentative definition has type '{s}' that is never completed";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const forward_declaration_here = struct {
+ const msg = "forward declaration of '{s}'";
+ const kind = .note;
+ const extra = .str;
+ };
+ pub const gnu_union_cast = struct {
+ const msg = "cast to union type is a GNU extension";
+ const opt = "gnu-union-cast";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const invalid_union_cast = struct {
+ const msg = "cast to union type from type '{s}' not present in union";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const cast_to_incomplete_type = struct {
+ const msg = "cast to incomplete type '{s}'";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const invalid_source_epoch = struct {
+ const msg = "environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799";
+ const kind = .@"error";
+ };
+ pub const fuse_ld_path = struct {
+ const msg = "'-fuse-ld=' taking a path is deprecated; use '--ld-path=' instead";
+ const kind = .off;
+ const opt = "fuse-ld-path";
+ };
+ pub const invalid_rtlib = struct {
+ const msg = "invalid runtime library name '{s}'";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const unsupported_rtlib_gcc = struct {
+ const msg = "unsupported runtime library 'libgcc' for platform '{s}'";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const invalid_unwindlib = struct {
+ const msg = "invalid unwind library name '{s}'";
+ const kind = .@"error";
+ const extra = .str;
+ };
+ pub const incompatible_unwindlib = struct {
+ const msg = "--rtlib=libgcc requires --unwindlib=libgcc";
+ const kind = .@"error";
+ };
+ pub const gnu_asm_disabled = struct {
+ const msg = "GNU-style inline assembly is disabled";
+ const kind = .@"error";
+ };
+ pub const extension_token_used = struct {
+ const msg = "extension used";
+ const kind = .off;
+ const pedantic = true;
+ const opt = "language-extension-token";
+ };
+ pub const complex_component_init = struct {
+ const msg = "complex initialization specifying real and imaginary components is an extension";
+ const opt = "complex-component-init";
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const complex_prefix_postfix_op = struct {
+ const msg = "ISO C does not support '++'/'--' on complex type '{s}'";
+ const opt = "pedantic";
+ const extra = .str;
+ const kind = .off;
+ const pedantic = true;
+ };
+ pub const not_floating_type = struct {
+ const msg = "argument type '{s}' is not a real floating point type";
+ const extra = .str;
+ const kind = .@"error";
+ };
+ pub const argument_types_differ = struct {
+ const msg = "arguments are of different types ({s})";
+ const extra = .str;
+ const kind = .@"error";
+ };
+};
+
+list: std.ArrayListUnmanaged(Message) = .{},
+arena: std.heap.ArenaAllocator,
+color: bool = true,
+fatal_errors: bool = false,
+options: Options = .{},
+errors: u32 = 0,
+macro_backtrace_limit: u32 = 6,
+
+pub fn warningExists(name: []const u8) bool {
+ inline for (std.meta.fields(Options)) |f| {
+ if (mem.eql(u8, f.name, name)) return true;
+ }
+ return false;
+}
+
+pub fn set(diag: *Diagnostics, name: []const u8, to: Kind) !void {
+ inline for (std.meta.fields(Options)) |f| {
+ if (mem.eql(u8, f.name, name)) {
+ @field(diag.options, f.name) = to;
+ return;
+ }
+ }
+ try diag.add(.{
+ .tag = .unknown_warning,
+ .extra = .{ .str = name },
+ }, &.{});
+}
+
+pub fn init(gpa: Allocator) Diagnostics {
+ return .{
+ .arena = std.heap.ArenaAllocator.init(gpa),
+ };
+}
+
+pub fn deinit(diag: *Diagnostics) void {
+ diag.list.deinit(diag.arena.allocator());
+ diag.arena.deinit();
+}
+
+pub fn add(diag: *Diagnostics, msg: Message, expansion_locs: []const Source.Location) Compilation.Error!void {
+ const kind = diag.tagKind(msg.tag);
+ if (kind == .off) return;
+ var copy = msg;
+ copy.kind = kind;
+
+ if (expansion_locs.len != 0) copy.loc = expansion_locs[expansion_locs.len - 1];
+ try diag.list.append(diag.arena.allocator(), copy);
+ if (expansion_locs.len != 0) {
+ // Add macro backtrace notes in reverse order omitting from the middle if needed.
+ var i = expansion_locs.len - 1;
+ const half = diag.macro_backtrace_limit / 2;
+ const limit = if (i < diag.macro_backtrace_limit) 0 else i - half;
+ try diag.list.ensureUnusedCapacity(
+ diag.arena.allocator(),
+ if (limit == 0) expansion_locs.len else diag.macro_backtrace_limit + 1,
+ );
+ while (i > limit) {
+ i -= 1;
+ diag.list.appendAssumeCapacity(.{
+ .tag = .expanded_from_here,
+ .kind = .note,
+ .loc = expansion_locs[i],
+ });
+ }
+ if (limit != 0) {
+ diag.list.appendAssumeCapacity(.{
+ .tag = .skipping_macro_backtrace,
+ .kind = .note,
+ .extra = .{ .unsigned = expansion_locs.len - diag.macro_backtrace_limit },
+ });
+ i = half - 1;
+ while (i > 0) {
+ i -= 1;
+ diag.list.appendAssumeCapacity(.{
+ .tag = .expanded_from_here,
+ .kind = .note,
+ .loc = expansion_locs[i],
+ });
+ }
+ }
+
+ diag.list.appendAssumeCapacity(.{
+ .tag = .expanded_from_here,
+ .kind = .note,
+ .loc = msg.loc,
+ });
+ }
+ if (kind == .@"fatal error" or (kind == .@"error" and diag.fatal_errors))
+ return error.FatalError;
+}
+
+pub fn fatal(
+ diag: *Diagnostics,
+ path: []const u8,
+ line: []const u8,
+ line_no: u32,
+ col: u32,
+ comptime fmt: []const u8,
+ args: anytype,
+) Compilation.Error {
+ var m = MsgWriter.init(diag.color);
+ defer m.deinit();
+
+ m.location(path, line_no, col);
+ m.start(.@"fatal error");
+ m.print(fmt, args);
+ m.end(line, col, false);
+
+ diag.errors += 1;
+ return error.FatalError;
+}
+
+pub fn fatalNoSrc(diag: *Diagnostics, comptime fmt: []const u8, args: anytype) error{FatalError} {
+ if (!diag.color) {
+ std.debug.print("fatal error: " ++ fmt ++ "\n", args);
+ } else {
+ const std_err = std.io.getStdErr().writer();
+ util.setColor(.red, std_err);
+ std_err.writeAll("fatal error: ") catch {};
+ util.setColor(.white, std_err);
+ std_err.print(fmt ++ "\n", args) catch {};
+ util.setColor(.reset, std_err);
+ }
+ diag.errors += 1;
+ return error.FatalError;
+}
+
+pub fn render(comp: *Compilation) void {
+ if (comp.diag.list.items.len == 0) return;
+ var m = defaultMsgWriter(comp);
+ defer m.deinit();
+ renderMessages(comp, &m);
+}
+pub fn defaultMsgWriter(comp: *const Compilation) MsgWriter {
+ return MsgWriter.init(comp.diag.color);
+}
+
+pub fn renderMessages(comp: *Compilation, m: anytype) void {
+ var errors: u32 = 0;
+ var warnings: u32 = 0;
+ for (comp.diag.list.items) |msg| {
+ switch (msg.kind) {
+ .@"fatal error", .@"error" => errors += 1,
+ .warning => warnings += 1,
+ .note => {},
+ .off => continue, // happens if an error is added before it is disabled
+ .default => unreachable,
+ }
+ renderMessage(comp, m, msg);
+ }
+ const w_s: []const u8 = if (warnings == 1) "" else "s";
+ const e_s: []const u8 = if (errors == 1) "" else "s";
+ if (errors != 0 and warnings != 0) {
+ m.print("{d} warning{s} and {d} error{s} generated.\n", .{ warnings, w_s, errors, e_s });
+ } else if (warnings != 0) {
+ m.print("{d} warning{s} generated.\n", .{ warnings, w_s });
+ } else if (errors != 0) {
+ m.print("{d} error{s} generated.\n", .{ errors, e_s });
+ }
+
+ comp.diag.list.items.len = 0;
+ comp.diag.errors += errors;
+}
+
+pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
+ var line: ?[]const u8 = null;
+ var end_with_splice = false;
+ const width = if (msg.loc.id != .unused) blk: {
+ var loc = msg.loc;
+ switch (msg.tag) {
+ .escape_sequence_overflow,
+ .invalid_universal_character,
+ .non_standard_escape_char,
+ // use msg.extra.unsigned for index into string literal
+ => loc.byte_offset += @truncate(msg.extra.unsigned),
+ else => {},
+ }
+ const source = comp.getSource(loc.id);
+ var line_col = source.lineCol(loc);
+ line = line_col.line;
+ end_with_splice = line_col.end_with_splice;
+ if (msg.tag == .backslash_newline_escape) {
+ line = line_col.line[0 .. line_col.col - 1];
+ line_col.col += 1;
+ line_col.width += 1;
+ }
+ m.location(source.path, line_col.line_no, line_col.col);
+ break :blk line_col.width;
+ } else 0;
+
+ m.start(msg.kind);
+ @setEvalBranchQuota(1500);
+ switch (msg.tag) {
+ inline else => |tag| {
+ const info = @field(messages, @tagName(tag));
+ if (@hasDecl(info, "extra")) {
+ switch (info.extra) {
+ .str => m.print(info.msg, .{msg.extra.str}),
+ .tok_id => m.print(info.msg, .{
+ msg.extra.tok_id.expected.symbol(),
+ msg.extra.tok_id.actual.symbol(),
+ }),
+ .tok_id_expected => m.print(info.msg, .{msg.extra.tok_id_expected.symbol()}),
+ .arguments => m.print(info.msg, .{ msg.extra.arguments.expected, msg.extra.arguments.actual }),
+ .codepoints => m.print(info.msg, .{
+ msg.extra.codepoints.actual,
+ msg.extra.codepoints.resembles,
+ }),
+ .attr_arg_count => m.print(info.msg, .{
+ @tagName(msg.extra.attr_arg_count.attribute),
+ msg.extra.attr_arg_count.expected,
+ }),
+ .attr_arg_type => m.print(info.msg, .{
+ msg.extra.attr_arg_type.expected.toString(),
+ msg.extra.attr_arg_type.actual.toString(),
+ }),
+ .actual_codepoint => m.print(info.msg, .{msg.extra.actual_codepoint}),
+ .ascii => m.print(info.msg, .{msg.extra.ascii}),
+ .unsigned => m.print(info.msg, .{msg.extra.unsigned}),
+ .pow_2_as_string => m.print(info.msg, .{switch (msg.extra.pow_2_as_string) {
+ 63 => "9223372036854775808",
+ 64 => "18446744073709551616",
+ 127 => "170141183460469231731687303715884105728",
+ 128 => "340282366920938463463374607431768211456",
+ else => unreachable,
+ }}),
+ .signed => m.print(info.msg, .{msg.extra.signed}),
+ .attr_enum => m.print(info.msg, .{
+ @tagName(msg.extra.attr_enum.tag),
+ Attribute.Formatting.choices(msg.extra.attr_enum.tag),
+ }),
+ .ignored_record_attr => m.print(info.msg, .{
+ @tagName(msg.extra.ignored_record_attr.tag),
+ @tagName(msg.extra.ignored_record_attr.specifier),
+ }),
+ .builtin_with_header => m.print(info.msg, .{
+ @tagName(msg.extra.builtin_with_header.header),
+ @tagName(msg.extra.builtin_with_header.builtin),
+ }),
+ else => @compileError("invalid extra kind " ++ @tagName(info.extra)),
+ }
+ } else {
+ m.write(info.msg);
+ }
+
+ if (@hasDecl(info, "opt")) {
+ if (msg.kind == .@"error" and info.kind != .@"error") {
+ m.print(" [-Werror,-W{s}]", .{info.opt});
+ } else if (msg.kind != .note) {
+ m.print(" [-W{s}]", .{info.opt});
+ }
+ }
+ },
+ }
+
+ m.end(line, width, end_with_splice);
+}
+
+fn tagKind(diag: *Diagnostics, tag: Tag) Kind {
+ // XXX: horrible hack, do not do this
+ const comp = @fieldParentPtr(Compilation, "diag", diag);
+
+ var kind: Kind = undefined;
+ switch (tag) {
+ inline else => |tag_val| {
+ const info = @field(messages, @tagName(tag_val));
+ kind = info.kind;
+
+ // stage1 doesn't like when I combine these ifs
+ if (@hasDecl(info, "all")) {
+ if (diag.options.all != .default) kind = diag.options.all;
+ }
+ if (@hasDecl(info, "w_extra")) {
+ if (diag.options.extra != .default) kind = diag.options.extra;
+ }
+ if (@hasDecl(info, "pedantic")) {
+ if (diag.options.pedantic != .default) kind = diag.options.pedantic;
+ }
+ if (@hasDecl(info, "opt")) {
+ if (@field(diag.options, info.opt) != .default) kind = @field(diag.options, info.opt);
+ }
+ if (@hasDecl(info, "suppress_version")) if (comp.langopts.standard.atLeast(info.suppress_version)) return .off;
+ if (@hasDecl(info, "suppress_unless_version")) if (!comp.langopts.standard.atLeast(info.suppress_unless_version)) return .off;
+ if (@hasDecl(info, "suppress_gnu")) if (comp.langopts.standard.isExplicitGNU()) return .off;
+ if (@hasDecl(info, "suppress_language_option")) if (!@field(comp.langopts, info.suppress_language_option)) return .off;
+ if (@hasDecl(info, "suppress_gcc")) if (comp.langopts.emulate == .gcc) return .off;
+ if (@hasDecl(info, "suppress_clang")) if (comp.langopts.emulate == .clang) return .off;
+ if (@hasDecl(info, "suppress_msvc")) if (comp.langopts.emulate == .msvc) return .off;
+ if (kind == .@"error" and diag.fatal_errors) kind = .@"fatal error";
+ return kind;
+ },
+ }
+}
+
+const MsgWriter = struct {
+ w: std.io.BufferedWriter(4096, std.fs.File.Writer),
+ color: bool,
+
+ fn init(color: bool) MsgWriter {
+ std.debug.getStderrMutex().lock();
+ return .{
+ .w = std.io.bufferedWriter(std.io.getStdErr().writer()),
+ .color = color,
+ };
+ }
+
+ pub fn deinit(m: *MsgWriter) void {
+ m.w.flush() catch {};
+ std.debug.getStderrMutex().unlock();
+ }
+
+ pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void {
+ m.w.writer().print(fmt, args) catch {};
+ }
+
+ fn write(m: *MsgWriter, msg: []const u8) void {
+ m.w.writer().writeAll(msg) catch {};
+ }
+
+ fn setColor(m: *MsgWriter, color: util.Color) void {
+ util.setColor(color, m.w.writer());
+ }
+
+ fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void {
+ const prefix = if (std.fs.path.dirname(path) == null and path[0] != '<') "." ++ std.fs.path.sep_str else "";
+ if (!m.color) {
+ m.print("{s}{s}:{d}:{d}: ", .{ prefix, path, line, col });
+ } else {
+ m.setColor(.white);
+ m.print("{s}{s}:{d}:{d}: ", .{ prefix, path, line, col });
+ }
+ }
+
+ fn start(m: *MsgWriter, kind: Kind) void {
+ if (!m.color) {
+ m.print("{s}: ", .{@tagName(kind)});
+ } else {
+ switch (kind) {
+ .@"fatal error", .@"error" => m.setColor(.red),
+ .note => m.setColor(.cyan),
+ .warning => m.setColor(.purple),
+ .off, .default => unreachable,
+ }
+ m.write(switch (kind) {
+ .@"fatal error" => "fatal error: ",
+ .@"error" => "error: ",
+ .note => "note: ",
+ .warning => "warning: ",
+ .off, .default => unreachable,
+ });
+ m.setColor(.white);
+ }
+ }
+
+ fn end(m: *MsgWriter, maybe_line: ?[]const u8, col: u32, end_with_splice: bool) void {
+ const line = maybe_line orelse {
+ m.write("\n");
+ return;
+ };
+ const trailer = if (end_with_splice) "\\ " else "";
+ if (!m.color) {
+ m.print("\n{s}{s}\n", .{ line, trailer });
+ m.print("{s: >[1]}^\n", .{ "", col });
+ } else {
+ m.setColor(.reset);
+ m.print("\n{s}{s}\n{s: >[3]}", .{ line, trailer, "", col });
+ m.setColor(.green);
+ m.write("^\n");
+ m.setColor(.reset);
+ }
+ }
+};
deps/aro/Driver.zig
@@ -0,0 +1,683 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const process = std.process;
+const Codegen = @import("Codegen_legacy.zig");
+const Compilation = @import("Compilation.zig");
+const LangOpts = @import("LangOpts.zig");
+const Preprocessor = @import("Preprocessor.zig");
+const Parser = @import("Parser.zig");
+const Source = @import("Source.zig");
+const Toolchain = @import("Toolchain.zig");
+const util = @import("util.zig");
+const target_util = @import("target.zig");
+
+const Driver = @This();
+
+pub const Linker = enum {
+ ld,
+ bfd,
+ gold,
+ lld,
+ mold,
+};
+
+comp: *Compilation,
+inputs: std.ArrayListUnmanaged(Source) = .{},
+link_objects: std.ArrayListUnmanaged([]const u8) = .{},
+output_name: ?[]const u8 = null,
+sysroot: ?[]const u8 = null,
+temp_file_count: u32 = 0,
+only_preprocess: bool = false,
+only_syntax: bool = false,
+only_compile: bool = false,
+only_preprocess_and_compile: bool = false,
+verbose_ast: bool = false,
+verbose_pp: bool = false,
+verbose_ir: bool = false,
+verbose_linker_args: bool = false,
+
+/// Full path to the aro executable
+aro_name: []const u8 = "",
+
+/// Value of --triple= passed via CLI
+raw_target_triple: ?[]const u8 = null,
+
+// linker options
+use_linker: ?[]const u8 = null,
+linker_path: ?[]const u8 = null,
+nodefaultlibs: bool = false,
+nolibc: bool = false,
+nostartfiles: bool = false,
+nostdlib: bool = false,
+pie: ?bool = null,
+rdynamic: bool = false,
+relocatable: bool = false,
+rtlib: ?[]const u8 = null,
+shared: bool = false,
+shared_libgcc: bool = false,
+static: bool = false,
+static_libgcc: bool = false,
+static_pie: bool = false,
+strip: bool = false,
+unwindlib: ?[]const u8 = null,
+
+pub fn deinit(d: *Driver) void {
+ for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
+ std.fs.deleteFileAbsolute(obj) catch {};
+ d.comp.gpa.free(obj);
+ }
+ d.inputs.deinit(d.comp.gpa);
+ d.link_objects.deinit(d.comp.gpa);
+ d.* = undefined;
+}
+
+pub const usage =
+ \\Usage {s}: [options] file..
+ \\
+ \\General options:
+ \\ -h, --help Print this message.
+ \\ -v, --version Print aro version.
+ \\
+ \\Compile options:
+ \\ -c, --compile Only run preprocess, compile, and assemble steps
+ \\ -D <macro>=<value> Define <macro> to <value> (defaults to 1)
+ \\ -E Only run the preprocessor
+ \\ -fchar8_t Enable char8_t (enabled by default in C2X and later)
+ \\ -fno-char8_t Disable char8_t (disabled by default for pre-C2X)
+ \\ -fcolor-diagnostics Enable colors in diagnostics
+ \\ -fno-color-diagnostics Disable colors in diagnostics
+ \\ -fdeclspec Enable support for __declspec attributes
+ \\ -fno-declspec Disable support for __declspec attributes
+ \\ -ffp-eval-method=[source|double|extended]
+ \\ Evaluation method to use for floating-point arithmetic
+ \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled)
+ \\ -fno-gnu-inline-asm Disable GNU style inline asm
+ \\ -fms-extensions Enable support for Microsoft extensions
+ \\ -fno-ms-extensions Disable support for Microsoft extensions
+ \\ -fdollars-in-identifiers
+ \\ Allow '$' in identifiers
+ \\ -fno-dollars-in-identifiers
+ \\ Disallow '$' in identifiers
+ \\ -fmacro-backtrace-limit=<limit>
+ \\ Set limit on how many macro expansion traces are shown in errors (default 6)
+ \\ -fnative-half-type Use the native half type for __fp16 instead of promoting to float
+ \\ -fnative-half-arguments-and-returns
+ \\ Allow half-precision function arguments and return values
+ \\ -fshort-enums Use the narrowest possible integer type for enums
+ \\ -fno-short-enums Use "int" as the tag type for enums
+ \\ -fsigned-char "char" is signed
+ \\ -fno-signed-char "char" is unsigned
+ \\ -fsyntax-only Only run the preprocessor, parser, and semantic analysis stages
+ \\ -funsigned-char "char" is unsigned
+ \\ -fno-unsigned-char "char" is signed
+ \\ -I <dir> Add directory to include search path
+ \\ -isystem Add directory to SYSTEM include search path
+ \\ --emulate=[clang|gcc|msvc]
+ \\ Select which C compiler to emulate (default clang)
+ \\ -o <file> Write output to <file>
+ \\ -pedantic Warn on language extensions
+ \\ --rtlib=<arg> Compiler runtime library to use (libgcc or compiler-rt)
+ \\ -std=<standard> Specify language standard
+ \\ -S, --assemble Only run preprocess and compilation steps
+ \\ --sysroot=<dir> Use dir as the logical root directory for headers and libraries (not fully implemented)
+ \\ --target=<value> Generate code for the given target
+ \\ -U <macro> Undefine <macro>
+ \\ -Werror Treat all warnings as errors
+ \\ -Werror=<warning> Treat warning as error
+ \\ -W<warning> Enable the specified warning
+ \\ -Wno-<warning> Disable the specified warning
+ \\
+ \\Link options:
+ \\ -fuse-ld=[bfd|gold|lld|mold]
+ \\ Use specific linker
+ \\ -nodefaultlibs Do not use the standard system libraries when linking.
+ \\ -nolibc Do not use the C library or system libraries tightly coupled with it when linking.
+ \\ -nostdlib Do not use the standard system startup files or libraries when linking
+ \\ -nostartfiles Do not use the standard system startup files when linking.
+ \\ -pie Produce a dynamically linked position independent executable on targets that support it.
+ \\ --ld-path=<path> Use linker specified by <path>
+ \\ -r Produce a relocatable object as output.
+ \\ -rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it.
+ \\ -s Remove all symbol table and relocation information from the executable.
+ \\ -shared Produce a shared object which can then be linked with other objects to form an executable.
+ \\ -shared-libgcc On systems that provide libgcc as a shared library, force the use of the shared version
+ \\ -static On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries.
+ \\ -static-libgcc On systems that provide libgcc as a shared library, force the use of the static version
+ \\ -static-pie Produce a static position independent executable on targets that support it.
+ \\ --unwindlib=<arg> Unwind library to use ("none", "libgcc", or "libunwind") If not specified, will match runtime library
+ \\
+ \\Debug options:
+ \\ --verbose-ast Dump produced AST to stdout
+ \\ --verbose-pp Dump preprocessor state
+ \\ --verbose-ir Dump ir to stdout
+ \\ --verbose-linker-args Dump linker args to stdout
+ \\
+ \\
+;
+
+/// Process command line arguments, returns true if something was written to std_out.
+pub fn parseArgs(
+ d: *Driver,
+ std_out: anytype,
+ macro_buf: anytype,
+ args: []const []const u8,
+) !bool {
+ var i: usize = 1;
+ var color_setting: enum {
+ on,
+ off,
+ unset,
+ } = .unset;
+ while (i < args.len) : (i += 1) {
+ const arg = args[i];
+ if (mem.startsWith(u8, arg, "-") and arg.len > 1) {
+ if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
+ std_out.print(usage, .{args[0]}) catch |er| {
+ return d.fatal("unable to print usage: {s}", .{util.errorDescription(er)});
+ };
+ return true;
+ } else if (mem.eql(u8, arg, "-v") or mem.eql(u8, arg, "--version")) {
+ std_out.writeAll(@import("lib.zig").version_str ++ "\n") catch |er| {
+ return d.fatal("unable to print version: {s}", .{util.errorDescription(er)});
+ };
+ return true;
+ } else if (mem.startsWith(u8, arg, "-D")) {
+ var macro = arg["-D".len..];
+ if (macro.len == 0) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -I");
+ continue;
+ }
+ macro = args[i];
+ }
+ var value: []const u8 = "1";
+ if (mem.indexOfScalar(u8, macro, '=')) |some| {
+ value = macro[some + 1 ..];
+ macro = macro[0..some];
+ }
+ try macro_buf.print("#define {s} {s}\n", .{ macro, value });
+ } else if (mem.startsWith(u8, arg, "-U")) {
+ var macro = arg["-U".len..];
+ if (macro.len == 0) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -I");
+ continue;
+ }
+ macro = args[i];
+ }
+ try macro_buf.print("#undef {s}\n", .{macro});
+ } else if (mem.eql(u8, arg, "-c") or mem.eql(u8, arg, "--compile")) {
+ d.only_compile = true;
+ } else if (mem.eql(u8, arg, "-E")) {
+ d.only_preprocess = true;
+ } else if (mem.eql(u8, arg, "-fchar8_t")) {
+ d.comp.langopts.has_char8_t_override = true;
+ } else if (mem.eql(u8, arg, "-fno-char8_t")) {
+ d.comp.langopts.has_char8_t_override = false;
+ } else if (mem.eql(u8, arg, "-fcolor-diagnostics")) {
+ color_setting = .on;
+ } else if (mem.eql(u8, arg, "-fno-color-diagnostics")) {
+ color_setting = .off;
+ } else if (mem.eql(u8, arg, "-fdollars-in-identifiers")) {
+ d.comp.langopts.dollars_in_identifiers = true;
+ } else if (mem.eql(u8, arg, "-fno-dollars-in-identifiers")) {
+ d.comp.langopts.dollars_in_identifiers = false;
+ } else if (mem.eql(u8, arg, "-fdigraphs")) {
+ d.comp.langopts.digraphs = true;
+ } else if (mem.eql(u8, arg, "-fgnu-inline-asm")) {
+ d.comp.langopts.gnu_asm = true;
+ } else if (mem.eql(u8, arg, "-fno-gnu-inline-asm")) {
+ d.comp.langopts.gnu_asm = false;
+ } else if (mem.eql(u8, arg, "-fno-digraphs")) {
+ d.comp.langopts.digraphs = false;
+ } else if (option(arg, "-fmacro-backtrace-limit=")) |limit_str| {
+ var limit = std.fmt.parseInt(u32, limit_str, 10) catch {
+ try d.err("-fmacro-backtrace-limit takes a number argument");
+ continue;
+ };
+
+ if (limit == 0) limit = std.math.maxInt(u32);
+ d.comp.diag.macro_backtrace_limit = limit;
+ } else if (mem.eql(u8, arg, "-fnative-half-type")) {
+ d.comp.langopts.use_native_half_type = true;
+ } else if (mem.eql(u8, arg, "-fnative-half-arguments-and-returns")) {
+ d.comp.langopts.allow_half_args_and_returns = true;
+ } else if (mem.eql(u8, arg, "-fshort-enums")) {
+ d.comp.langopts.short_enums = true;
+ } else if (mem.eql(u8, arg, "-fno-short-enums")) {
+ d.comp.langopts.short_enums = false;
+ } else if (mem.eql(u8, arg, "-fsigned-char")) {
+ d.comp.langopts.setCharSignedness(.signed);
+ } else if (mem.eql(u8, arg, "-fno-signed-char")) {
+ d.comp.langopts.setCharSignedness(.unsigned);
+ } else if (mem.eql(u8, arg, "-funsigned-char")) {
+ d.comp.langopts.setCharSignedness(.unsigned);
+ } else if (mem.eql(u8, arg, "-fno-unsigned-char")) {
+ d.comp.langopts.setCharSignedness(.signed);
+ } else if (mem.eql(u8, arg, "-fdeclspec")) {
+ d.comp.langopts.declspec_attrs = true;
+ } else if (mem.eql(u8, arg, "-fno-declspec")) {
+ d.comp.langopts.declspec_attrs = false;
+ } else if (mem.eql(u8, arg, "-fms-extensions")) {
+ d.comp.langopts.enableMSExtensions();
+ } else if (mem.eql(u8, arg, "-fno-ms-extensions")) {
+ d.comp.langopts.disableMSExtensions();
+ } else if (mem.startsWith(u8, arg, "-I")) {
+ var path = arg["-I".len..];
+ if (path.len == 0) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -I");
+ continue;
+ }
+ path = args[i];
+ }
+ try d.comp.include_dirs.append(path);
+ } else if (mem.startsWith(u8, arg, "-fsyntax-only")) {
+ d.only_syntax = true;
+ } else if (mem.startsWith(u8, arg, "-fno-syntax-only")) {
+ d.only_syntax = false;
+ } else if (mem.startsWith(u8, arg, "-isystem")) {
+ var path = arg["-isystem".len..];
+ if (path.len == 0) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -isystem");
+ continue;
+ }
+ path = args[i];
+ }
+ const duped = try d.comp.gpa.dupe(u8, path);
+ errdefer d.comp.gpa.free(duped);
+ try d.comp.system_include_dirs.append(duped);
+ } else if (option(arg, "--emulate=")) |compiler_str| {
+ const compiler = std.meta.stringToEnum(LangOpts.Compiler, compiler_str) orelse {
+ try d.comp.diag.add(.{ .tag = .cli_invalid_emulate, .extra = .{ .str = arg } }, &.{});
+ continue;
+ };
+ d.comp.langopts.setEmulatedCompiler(compiler);
+ } else if (option(arg, "-ffp-eval-method=")) |fp_method_str| {
+ const fp_eval_method = std.meta.stringToEnum(LangOpts.FPEvalMethod, fp_method_str) orelse .indeterminate;
+ if (fp_eval_method == .indeterminate) {
+ try d.comp.diag.add(.{ .tag = .cli_invalid_fp_eval_method, .extra = .{ .str = fp_method_str } }, &.{});
+ continue;
+ }
+ d.comp.langopts.setFpEvalMethod(fp_eval_method);
+ } else if (mem.startsWith(u8, arg, "-o")) {
+ var file = arg["-o".len..];
+ if (file.len == 0) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -o");
+ continue;
+ }
+ file = args[i];
+ }
+ d.output_name = file;
+ } else if (option(arg, "--sysroot=")) |sysroot| {
+ d.sysroot = sysroot;
+ } else if (mem.eql(u8, arg, "-pedantic")) {
+ d.comp.diag.options.pedantic = .warning;
+ } else if (option(arg, "--rtlib=")) |rtlib| {
+ if (mem.eql(u8, rtlib, "compiler-rt") or mem.eql(u8, rtlib, "libgcc") or mem.eql(u8, rtlib, "platform")) {
+ d.rtlib = rtlib;
+ } else {
+ try d.comp.diag.add(.{ .tag = .invalid_rtlib, .extra = .{ .str = rtlib } }, &.{});
+ }
+ } else if (option(arg, "-Werror=")) |err_name| {
+ try d.comp.diag.set(err_name, .@"error");
+ } else if (mem.eql(u8, arg, "-Wno-fatal-errors")) {
+ d.comp.diag.fatal_errors = false;
+ } else if (option(arg, "-Wno-")) |err_name| {
+ try d.comp.diag.set(err_name, .off);
+ } else if (mem.eql(u8, arg, "-Wfatal-errors")) {
+ d.comp.diag.fatal_errors = true;
+ } else if (option(arg, "-W")) |err_name| {
+ try d.comp.diag.set(err_name, .warning);
+ } else if (option(arg, "-std=")) |standard| {
+ d.comp.langopts.setStandard(standard) catch
+ try d.comp.diag.add(.{ .tag = .cli_invalid_standard, .extra = .{ .str = arg } }, &.{});
+ } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) {
+ d.only_preprocess_and_compile = true;
+ } else if (option(arg, "--target=")) |triple| {
+ const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = triple }) catch {
+ try d.comp.diag.add(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{});
+ continue;
+ };
+ d.comp.target = cross.toTarget(); // TODO deprecated
+ d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(d.comp.target));
+ d.raw_target_triple = triple;
+ } else if (mem.eql(u8, arg, "--verbose-ast")) {
+ d.verbose_ast = true;
+ } else if (mem.eql(u8, arg, "--verbose-pp")) {
+ d.verbose_pp = true;
+ } else if (mem.eql(u8, arg, "--verbose-ir")) {
+ d.verbose_ir = true;
+ } else if (mem.eql(u8, arg, "--verbose-linker-args")) {
+ d.verbose_linker_args = true;
+ } else if (option(arg, "-fuse-ld=")) |linker_name| {
+ d.use_linker = linker_name;
+ } else if (mem.eql(u8, arg, "-fuse-ld=")) {
+ d.use_linker = null;
+ } else if (option(arg, "--ld-path=")) |linker_path| {
+ d.linker_path = linker_path;
+ } else if (mem.eql(u8, arg, "-r")) {
+ d.relocatable = true;
+ } else if (mem.eql(u8, arg, "-shared")) {
+ d.shared = true;
+ } else if (mem.eql(u8, arg, "-shared-libgcc")) {
+ d.shared_libgcc = true;
+ } else if (mem.eql(u8, arg, "-static")) {
+ d.static = true;
+ } else if (mem.eql(u8, arg, "-static-libgcc")) {
+ d.static_libgcc = true;
+ } else if (mem.eql(u8, arg, "-static-pie")) {
+ d.static_pie = true;
+ } else if (mem.eql(u8, arg, "-pie")) {
+ d.pie = true;
+ } else if (mem.eql(u8, arg, "-no-pie") or mem.eql(u8, arg, "-nopie")) {
+ d.pie = false;
+ } else if (mem.eql(u8, arg, "-rdynamic")) {
+ d.rdynamic = true;
+ } else if (mem.eql(u8, arg, "-s")) {
+ d.strip = true;
+ } else if (mem.eql(u8, arg, "-nodefaultlibs")) {
+ d.nodefaultlibs = true;
+ } else if (mem.eql(u8, arg, "-nolibc")) {
+ d.nolibc = true;
+ } else if (mem.eql(u8, arg, "-nostdlib")) {
+ d.nostdlib = true;
+ } else if (mem.eql(u8, arg, "-nostartfiles")) {
+ d.nostartfiles = true;
+ } else if (option(arg, "--unwindlib=")) |unwindlib| {
+ const valid_unwindlibs: [5][]const u8 = .{ "", "none", "platform", "libunwind", "libgcc" };
+ for (valid_unwindlibs) |name| {
+ if (mem.eql(u8, name, unwindlib)) {
+ d.unwindlib = unwindlib;
+ break;
+ }
+ } else {
+ try d.comp.diag.add(.{ .tag = .invalid_unwindlib, .extra = .{ .str = unwindlib } }, &.{});
+ }
+ } else {
+ try d.comp.diag.add(.{ .tag = .cli_unknown_arg, .extra = .{ .str = arg } }, &.{});
+ }
+ } else if (std.mem.endsWith(u8, arg, ".o") or std.mem.endsWith(u8, arg, ".obj")) {
+ try d.link_objects.append(d.comp.gpa, arg);
+ } else {
+ const source = d.addSource(arg) catch |er| {
+ return d.fatal("unable to add source file '{s}': {s}", .{ arg, util.errorDescription(er) });
+ };
+ try d.inputs.append(d.comp.gpa, source);
+ }
+ }
+ d.comp.diag.color = switch (color_setting) {
+ .on => true,
+ .off => false,
+ .unset => util.fileSupportsColor(std.io.getStdErr()) and !std.process.hasEnvVarConstant("NO_COLOR"),
+ };
+ return false;
+}
+
+fn option(arg: []const u8, name: []const u8) ?[]const u8 {
+ if (std.mem.startsWith(u8, arg, name) and arg.len > name.len) {
+ return arg[name.len..];
+ }
+ return null;
+}
+
+fn addSource(d: *Driver, path: []const u8) !Source {
+ if (mem.eql(u8, "-", path)) {
+ const stdin = std.io.getStdIn().reader();
+ const input = try stdin.readAllAlloc(d.comp.gpa, std.math.maxInt(u32));
+ defer d.comp.gpa.free(input);
+ return d.comp.addSourceFromBuffer("<stdin>", input);
+ }
+ return d.comp.addSourceFromPath(path);
+}
+
+pub fn err(d: *Driver, msg: []const u8) !void {
+ try d.comp.diag.add(.{ .tag = .cli_error, .extra = .{ .str = msg } }, &.{});
+}
+
+pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{FatalError} {
+ d.comp.renderErrors();
+ return d.comp.diag.fatalNoSrc(fmt, args);
+}
+
+pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8) !void {
+ var macro_buf = std.ArrayList(u8).init(d.comp.gpa);
+ defer macro_buf.deinit();
+
+ const std_out = std.io.getStdOut().writer();
+ if (try parseArgs(d, std_out, macro_buf.writer(), args)) return;
+
+ const linking = !(d.only_preprocess or d.only_syntax or d.only_compile or d.only_preprocess_and_compile);
+
+ if (d.inputs.items.len == 0) {
+ return d.fatal("no input files", .{});
+ } else if (d.inputs.items.len != 1 and d.output_name != null and !linking) {
+ return d.fatal("cannot specify -o when generating multiple output files", .{});
+ }
+
+ if (!linking) for (d.link_objects.items) |obj| {
+ try d.comp.diag.add(.{ .tag = .cli_unused_link_object, .extra = .{ .str = obj } }, &.{});
+ };
+
+ d.comp.defineSystemIncludes(d.aro_name) catch |er| switch (er) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.AroIncludeNotFound => return d.fatal("unable to find Aro builtin headers", .{}),
+ };
+
+ const builtin = try d.comp.generateBuiltinMacros();
+ const user_macros = try d.comp.addSourceFromBuffer("<command line>", macro_buf.items);
+
+ const fast_exit = @import("builtin").mode != .Debug;
+
+ if (fast_exit and d.inputs.items.len == 1) {
+ d.processSource(tc, d.inputs.items[0], builtin, user_macros, fast_exit) catch |e| switch (e) {
+ error.FatalError => {
+ d.comp.renderErrors();
+ d.exitWithCleanup(1);
+ },
+ else => |er| return er,
+ };
+ unreachable;
+ }
+
+ for (d.inputs.items) |source| {
+ d.processSource(tc, source, builtin, user_macros, fast_exit) catch |e| switch (e) {
+ error.FatalError => {
+ d.comp.renderErrors();
+ },
+ else => |er| return er,
+ };
+ }
+ if (d.comp.diag.errors != 0) {
+ if (fast_exit) d.exitWithCleanup(1);
+ return;
+ }
+ if (linking) {
+ try d.invokeLinker(tc, fast_exit);
+ }
+ if (fast_exit) std.process.exit(0);
+}
+
+fn processSource(
+ d: *Driver,
+ tc: *Toolchain,
+ source: Source,
+ builtin: Source,
+ user_macros: Source,
+ comptime fast_exit: bool,
+) !void {
+ d.comp.generated_buf.items.len = 0;
+ var pp = Preprocessor.init(d.comp);
+ defer pp.deinit();
+
+ if (d.verbose_pp) pp.verbose = true;
+ if (d.only_preprocess) pp.preserve_whitespace = true;
+ try pp.addBuiltinMacros();
+
+ _ = try pp.preprocess(builtin);
+ _ = try pp.preprocess(user_macros);
+ const eof = try pp.preprocess(source);
+ try pp.tokens.append(pp.comp.gpa, eof);
+
+ if (d.only_preprocess) {
+ d.comp.renderErrors();
+
+ const file = if (d.output_name) |some|
+ std.fs.cwd().createFile(some, .{}) catch |er|
+ return d.fatal("unable to create output file '{s}': {s}", .{ some, util.errorDescription(er) })
+ else
+ std.io.getStdOut();
+ defer if (d.output_name != null) file.close();
+
+ var buf_w = std.io.bufferedWriter(file.writer());
+ pp.prettyPrintTokens(buf_w.writer()) catch |er|
+ return d.fatal("unable to write result: {s}", .{util.errorDescription(er)});
+
+ buf_w.flush() catch |er|
+ return d.fatal("unable to write result: {s}", .{util.errorDescription(er)});
+ if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
+ return;
+ }
+
+ var tree = try Parser.parse(&pp);
+ defer tree.deinit();
+
+ if (d.verbose_ast) {
+ const stdout = std.io.getStdOut();
+ var buf_writer = std.io.bufferedWriter(stdout.writer());
+ const color = d.comp.diag.color and util.fileSupportsColor(stdout);
+ tree.dump(color, buf_writer.writer()) catch {};
+ buf_writer.flush() catch {};
+ }
+
+ const prev_errors = d.comp.diag.errors;
+ d.comp.renderErrors();
+
+ if (d.comp.diag.errors != prev_errors) {
+ if (fast_exit) d.exitWithCleanup(1);
+ return; // do not compile if there were errors
+ }
+
+ if (d.only_syntax) {
+ if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
+ return;
+ }
+
+ if (d.comp.target.ofmt != .elf or d.comp.target.cpu.arch != .x86_64) {
+ return d.fatal(
+ "unsupported target {s}-{s}-{s}, currently only x86-64 elf is supported",
+ .{ @tagName(d.comp.target.cpu.arch), @tagName(d.comp.target.os.tag), @tagName(d.comp.target.abi) },
+ );
+ }
+
+ if (d.verbose_ir) {
+ try @import("CodeGen.zig").generateTree(d.comp, tree);
+ }
+
+ const obj = try Codegen.generateTree(d.comp, tree);
+ defer obj.deinit();
+
+ // If it's used, name_buf will either hold a filename or `/tmp/<12 random bytes with base-64 encoding>.<extension>`
+ // both of which should fit into MAX_NAME_BYTES for all systems
+ var name_buf: [std.fs.MAX_NAME_BYTES]u8 = undefined;
+
+ const out_file_name = if (d.only_compile) blk: {
+ const fmt_template = "{s}{s}";
+ const fmt_args = .{
+ std.fs.path.stem(source.path),
+ d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
+ };
+ break :blk d.output_name orelse
+ std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
+ } else blk: {
+ const random_bytes_count = 12;
+ const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);
+
+ var random_bytes: [random_bytes_count]u8 = undefined;
+ std.crypto.random.bytes(&random_bytes);
+ var random_name: [sub_path_len]u8 = undefined;
+ _ = std.fs.base64_encoder.encode(&random_name, &random_bytes);
+
+ const fmt_template = "/tmp/{s}{s}";
+ const fmt_args = .{
+ random_name,
+ d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
+ };
+ break :blk std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
+ };
+
+ const out_file = std.fs.cwd().createFile(out_file_name, .{}) catch |er|
+ return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, util.errorDescription(er) });
+ defer out_file.close();
+
+ obj.finish(out_file) catch |er|
+ return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, util.errorDescription(er) });
+
+ if (d.only_compile) {
+ if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
+ return;
+ }
+ try d.link_objects.ensureUnusedCapacity(d.comp.gpa, 1);
+ d.link_objects.appendAssumeCapacity(try d.comp.gpa.dupe(u8, out_file_name));
+ d.temp_file_count += 1;
+ if (fast_exit) {
+ try d.invokeLinker(tc, fast_exit);
+ }
+}
+
+fn dumpLinkerArgs(items: []const []const u8) !void {
+ const stdout = std.io.getStdOut().writer();
+ for (items, 0..) |item, i| {
+ if (i > 0) try stdout.writeByte(' ');
+ try stdout.print("\"{}\"", .{std.zig.fmtEscapes(item)});
+ }
+ try stdout.writeByte('\n');
+}
+
+pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) !void {
+ try tc.discover();
+
+ var argv = std.ArrayList([]const u8).init(d.comp.gpa);
+ defer argv.deinit();
+
+ var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ const linker_path = try tc.getLinkerPath(&linker_path_buf);
+ try argv.append(linker_path);
+
+ try tc.buildLinkerArgs(&argv);
+
+ if (d.verbose_linker_args) {
+ dumpLinkerArgs(argv.items) catch |er| {
+ return d.fatal("unable to dump linker args: {s}", .{util.errorDescription(er)});
+ };
+ }
+ var child = std.ChildProcess.init(argv.items, d.comp.gpa);
+ // TODO handle better
+ child.stdin_behavior = .Inherit;
+ child.stdout_behavior = .Inherit;
+ child.stderr_behavior = .Inherit;
+
+ const term = child.spawnAndWait() catch |er| {
+ return d.fatal("unable to spawn linker: {s}", .{util.errorDescription(er)});
+ };
+ switch (term) {
+ .Exited => |code| if (code != 0) d.exitWithCleanup(code),
+ else => std.process.abort(),
+ }
+ if (fast_exit) d.exitWithCleanup(0);
+}
+
+fn exitWithCleanup(d: *Driver, code: u8) noreturn {
+ for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
+ std.fs.deleteFileAbsolute(obj) catch {};
+ }
+ std.process.exit(code);
+}
deps/aro/features.zig
@@ -0,0 +1,76 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const target_util = @import("target.zig");
+
+/// Used to implement the __has_feature macro.
+pub fn hasFeature(comp: *Compilation, ext: []const u8) bool {
+ const list = .{
+ .assume_nonnull = true,
+ .attribute_analyzer_noreturn = true,
+ .attribute_availability = true,
+ .attribute_availability_with_message = true,
+ .attribute_availability_app_extension = true,
+ .attribute_availability_with_version_underscores = true,
+ .attribute_availability_tvos = true,
+ .attribute_availability_watchos = true,
+ .attribute_availability_with_strict = true,
+ .attribute_availability_with_replacement = true,
+ .attribute_availability_in_templates = true,
+ .attribute_availability_swift = true,
+ .attribute_cf_returns_not_retained = true,
+ .attribute_cf_returns_retained = true,
+ .attribute_cf_returns_on_parameters = true,
+ .attribute_deprecated_with_message = true,
+ .attribute_deprecated_with_replacement = true,
+ .attribute_ext_vector_type = true,
+ .attribute_ns_returns_not_retained = true,
+ .attribute_ns_returns_retained = true,
+ .attribute_ns_consumes_self = true,
+ .attribute_ns_consumed = true,
+ .attribute_cf_consumed = true,
+ .attribute_overloadable = true,
+ .attribute_unavailable_with_message = true,
+ .attribute_unused_on_fields = true,
+ .attribute_diagnose_if_objc = true,
+ .blocks = false, // TODO
+ .c_thread_safety_attributes = true,
+ .enumerator_attributes = true,
+ .nullability = true,
+ .nullability_on_arrays = true,
+ .nullability_nullable_result = true,
+ .c_alignas = comp.langopts.standard.atLeast(.c11),
+ .c_alignof = comp.langopts.standard.atLeast(.c11),
+ .c_atomic = comp.langopts.standard.atLeast(.c11),
+ .c_generic_selections = comp.langopts.standard.atLeast(.c11),
+ .c_static_assert = comp.langopts.standard.atLeast(.c11),
+ .c_thread_local = comp.langopts.standard.atLeast(.c11) and target_util.isTlsSupported(comp.target),
+ };
+ inline for (std.meta.fields(@TypeOf(list))) |f| {
+ if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
+ }
+ return false;
+}
+
+/// Used to implement the __has_extension macro.
+pub fn hasExtension(comp: *Compilation, ext: []const u8) bool {
+ const list = .{
+ // C11 features
+ .c_alignas = true,
+ .c_alignof = true,
+ .c_atomic = false, // TODO
+ .c_generic_selections = true,
+ .c_static_assert = true,
+ .c_thread_local = target_util.isTlsSupported(comp.target),
+ // misc
+ .overloadable_unmarked = false, // TODO
+ .statement_attributes_with_gnu_syntax = false, // TODO
+ .gnu_asm = true,
+ .gnu_asm_goto_with_outputs = true,
+ .matrix_types = false, // TODO
+ .matrix_types_scalar_division = false, // TODO
+ };
+ inline for (std.meta.fields(@TypeOf(list))) |f| {
+ if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
+ }
+ return false;
+}
deps/aro/InitList.zig
@@ -0,0 +1,153 @@
+//! Sparsely populated list of used indexes.
+//! Used for detecting duplicate initializers.
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const testing = std.testing;
+const Tree = @import("Tree.zig");
+const Token = Tree.Token;
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const NodeList = std.ArrayList(NodeIndex);
+const Parser = @import("Parser.zig");
+
+const InitList = @This();
+
+const Item = struct {
+ list: InitList = .{},
+ index: u64,
+
+ fn order(_: void, a: Item, b: Item) std.math.Order {
+ return std.math.order(a.index, b.index);
+ }
+};
+
+list: std.ArrayListUnmanaged(Item) = .{},
+node: NodeIndex = .none,
+tok: TokenIndex = 0,
+
+/// Deinitialize freeing all memory.
+pub fn deinit(il: *InitList, gpa: Allocator) void {
+ for (il.list.items) |*item| item.list.deinit(gpa);
+ il.list.deinit(gpa);
+ il.* = undefined;
+}
+
+/// Insert initializer at index, returning previous entry if one exists.
+pub fn put(il: *InitList, gpa: Allocator, index: usize, node: NodeIndex, tok: TokenIndex) !?TokenIndex {
+ const items = il.list.items;
+ var left: usize = 0;
+ var right: usize = items.len;
+
+ // Append new value to empty list
+ if (left == right) {
+ const item = try il.list.addOne(gpa);
+ item.* = .{
+ .list = .{ .node = node, .tok = tok },
+ .index = index,
+ };
+ return null;
+ }
+
+ while (left < right) {
+ // Avoid overflowing in the midpoint calculation
+ const mid = left + (right - left) / 2;
+ // Compare the key with the midpoint element
+ switch (std.math.order(index, items[mid].index)) {
+ .eq => {
+ // Replace previous entry.
+ const prev = items[mid].list.tok;
+ items[mid].list.deinit(gpa);
+ items[mid] = .{
+ .list = .{ .node = node, .tok = tok },
+ .index = index,
+ };
+ return prev;
+ },
+ .gt => left = mid + 1,
+ .lt => right = mid,
+ }
+ }
+
+ // Insert a new value into a sorted position.
+ try il.list.insert(gpa, left, .{
+ .list = .{ .node = node, .tok = tok },
+ .index = index,
+ });
+ return null;
+}
+
+/// Find item at index, create new if one does not exist.
+pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
+ const items = il.list.items;
+ var left: usize = 0;
+ var right: usize = items.len;
+
+ // Append new value to empty list
+ if (left == right) {
+ const item = try il.list.addOne(gpa);
+ item.* = .{
+ .list = .{ .node = .none, .tok = 0 },
+ .index = index,
+ };
+ return &item.list;
+ }
+
+ while (left < right) {
+ // Avoid overflowing in the midpoint calculation
+ const mid = left + (right - left) / 2;
+ // Compare the key with the midpoint element
+ switch (std.math.order(index, items[mid].index)) {
+ .eq => return &items[mid].list,
+ .gt => left = mid + 1,
+ .lt => right = mid,
+ }
+ }
+
+ // Insert a new value into a sorted position.
+ try il.list.insert(gpa, left, .{
+ .list = .{ .node = .none, .tok = 0 },
+ .index = index,
+ });
+ return &il.list.items[left].list;
+}
+
+test "basic usage" {
+ const gpa = testing.allocator;
+ var il: InitList = .{};
+ defer il.deinit(gpa);
+
+ {
+ var i: usize = 0;
+ while (i < 5) : (i += 1) {
+ const prev = try il.put(gpa, i, .none, 0);
+ try testing.expect(prev == null);
+ }
+ }
+
+ {
+ const failing = testing.failing_allocator;
+ var i: usize = 0;
+ while (i < 5) : (i += 1) {
+ _ = try il.find(failing, i);
+ }
+ }
+
+ {
+ var item = try il.find(gpa, 0);
+ var i: usize = 1;
+ while (i < 5) : (i += 1) {
+ item = try item.find(gpa, i);
+ }
+ }
+
+ {
+ const failing = testing.failing_allocator;
+ var item = try il.find(failing, 0);
+ var i: usize = 1;
+ while (i < 5) : (i += 1) {
+ item = try item.find(failing, i);
+ }
+ }
+}
deps/aro/Interner.zig
@@ -0,0 +1,180 @@
+const Interner = @This();
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
+const Value = @import("Value.zig");
+
+map: std.ArrayHashMapUnmanaged(Key, void, KeyContext, false) = .{},
+
+const KeyContext = struct {
+ pub fn eql(_: @This(), a: Key, b: Key, _: usize) bool {
+ return b.eql(a);
+ }
+
+ pub fn hash(_: @This(), a: Key) u32 {
+ return a.hash();
+ }
+};
+
+pub const Key = union(enum) {
+ int: u16,
+ float: u16,
+ ptr,
+ noreturn,
+ void,
+ func,
+ array: struct {
+ len: u64,
+ child: Ref,
+ },
+ vector: struct {
+ len: u32,
+ child: Ref,
+ },
+ value: Value,
+ record: struct {
+ /// Pointer to user data, value used for hash and equality check.
+ user_ptr: *anyopaque,
+ /// TODO make smaller if Value is made smaller
+ elements: []const Ref,
+ },
+
+ pub fn hash(key: Key) u32 {
+ var hasher = std.hash.Wyhash.init(0);
+ switch (key) {
+ .value => |val| {
+ std.hash.autoHash(&hasher, val.tag);
+ switch (val.tag) {
+ .unavailable => unreachable,
+ .nullptr_t => std.hash.autoHash(&hasher, @as(u64, 0)),
+ .int => std.hash.autoHash(&hasher, val.data.int),
+ .float => std.hash.autoHash(&hasher, @as(u64, @bitCast(val.data.float))),
+ .bytes => std.hash.autoHashStrat(&hasher, val.data.bytes, .Shallow),
+ }
+ },
+ .record => |info| {
+ std.hash.autoHash(&hasher, @intFromPtr(info.user_ptr));
+ },
+ inline else => |info| {
+ std.hash.autoHash(&hasher, info);
+ },
+ }
+ return @truncate(hasher.final());
+ }
+
+ pub fn eql(a: Key, b: Key) bool {
+ const KeyTag = std.meta.Tag(Key);
+ const a_tag: KeyTag = a;
+ const b_tag: KeyTag = b;
+ if (a_tag != b_tag) return false;
+ switch (a) {
+ .value => |a_info| {
+ const b_info = b.value;
+ if (a_info.tag != b_info.tag) return false;
+ switch (a_info.tag) {
+ .unavailable => unreachable,
+ .nullptr_t => return true,
+ .int => return a_info.data.int == b_info.data.int,
+ .float => return a_info.data.float == b_info.data.float,
+ .bytes => return a_info.data.bytes.start == b_info.data.bytes.start and a_info.data.bytes.end == b_info.data.bytes.end,
+ }
+ },
+ .record => |a_info| {
+ return a_info.user_ptr == b.record.user_ptr;
+ },
+ inline else => |a_info, tag| {
+ const b_info = @field(b, @tagName(tag));
+ return std.meta.eql(a_info, b_info);
+ },
+ }
+ }
+
+ fn toRef(key: Key) ?Ref {
+ switch (key) {
+ .int => |bits| switch (bits) {
+ 1 => return .i1,
+ 8 => return .i8,
+ 16 => return .i16,
+ 32 => return .i32,
+ 64 => return .i64,
+ 128 => return .i128,
+ else => {},
+ },
+ .float => |bits| switch (bits) {
+ 16 => return .f16,
+ 32 => return .f32,
+ 64 => return .f64,
+ 80 => return .f80,
+ 128 => return .f128,
+ else => unreachable,
+ },
+ .ptr => return .ptr,
+ .func => return .func,
+ .noreturn => return .noreturn,
+ .void => return .void,
+ else => {},
+ }
+ return null;
+ }
+};
+
+pub const Ref = enum(u32) {
+ const max = std.math.maxInt(u32);
+
+ ptr = max - 0,
+ noreturn = max - 1,
+ void = max - 2,
+ i1 = max - 3,
+ i8 = max - 4,
+ i16 = max - 5,
+ i32 = max - 6,
+ i64 = max - 7,
+ i128 = max - 8,
+ f16 = max - 9,
+ f32 = max - 10,
+ f64 = max - 11,
+ f80 = max - 12,
+ f128 = max - 13,
+ func = max - 14,
+ _,
+};
+
+pub fn deinit(ip: *Interner, gpa: Allocator) void {
+ ip.map.deinit(gpa);
+}
+
+pub fn put(ip: *Interner, gpa: Allocator, key: Key) !Ref {
+ if (key.toRef()) |some| return some;
+ const gop = try ip.map.getOrPut(gpa, key);
+ return @enumFromInt(gop.index);
+}
+
+pub fn has(ip: *Interner, key: Key) ?Ref {
+ if (key.toRef()) |some| return some;
+ if (ip.map.getIndex(key)) |index| {
+ return @enumFromInt(index);
+ }
+ return null;
+}
+
+pub fn get(ip: Interner, ref: Ref) Key {
+ switch (ref) {
+ .ptr => return .ptr,
+ .func => return .func,
+ .noreturn => return .noreturn,
+ .void => return .void,
+ .i1 => return .{ .int = 1 },
+ .i8 => return .{ .int = 8 },
+ .i16 => return .{ .int = 16 },
+ .i32 => return .{ .int = 32 },
+ .i64 => return .{ .int = 64 },
+ .i128 => return .{ .int = 128 },
+ .f16 => return .{ .float = 16 },
+ .f32 => return .{ .float = 32 },
+ .f64 => return .{ .float = 64 },
+ .f80 => return .{ .float = 80 },
+ .f128 => return .{ .float = 128 },
+ else => {},
+ }
+ return ip.map.keys()[@intFromEnum(ref)];
+}
deps/aro/Ir.zig
@@ -0,0 +1,601 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const Allocator = std.mem.Allocator;
+const Compilation = @import("Compilation.zig");
+const Interner = @import("Interner.zig");
+const StringId = @import("StringInterner.zig").StringId;
+const Value = @import("Value.zig");
+
+const Ir = @This();
+
+pool: Interner,
+strings: []const u8,
+// decls: std.StringArrayHashMapUnmanaged(Decl),
+
+// pub const Decl = struct {
+instructions: std.MultiArrayList(Inst),
+body: std.ArrayListUnmanaged(Ref),
+arena: std.heap.ArenaAllocator.State,
+// };
+
+pub const Builder = struct {
+ gpa: Allocator,
+ arena: std.heap.ArenaAllocator,
+ instructions: std.MultiArrayList(Ir.Inst) = .{},
+ body: std.ArrayListUnmanaged(Ref) = .{},
+ alloc_count: u32 = 0,
+ arg_count: u32 = 0,
+ pool: Interner = .{},
+ current_label: Ref = undefined,
+
+ pub fn deinit(b: *Builder) void {
+ b.arena.deinit();
+ b.instructions.deinit(b.gpa);
+ b.body.deinit(b.gpa);
+ b.pool.deinit(b.gpa);
+ b.* = undefined;
+ }
+
+ pub fn startFn(b: *Builder) Allocator.Error!void {
+ b.alloc_count = 0;
+ b.arg_count = 0;
+ b.instructions.len = 0;
+ b.body.items.len = 0;
+ const entry = try b.makeLabel("entry");
+ try b.body.append(b.gpa, entry);
+ b.current_label = entry;
+ }
+
+ pub fn startBlock(b: *Builder, label: Ref) !void {
+ try b.body.append(b.gpa, label);
+ b.current_label = label;
+ }
+
+ pub fn addArg(b: *Builder, ty: Interner.Ref) Allocator.Error!Ref {
+ const ref: Ref = @enumFromInt(b.instructions.len);
+ try b.instructions.append(b.gpa, .{ .tag = .arg, .data = .{ .none = {} }, .ty = ty });
+ try b.body.insert(b.gpa, b.arg_count, ref);
+ b.arg_count += 1;
+ return ref;
+ }
+
+ pub fn addAlloc(b: *Builder, size: u32, @"align": u32) Allocator.Error!Ref {
+ const ref: Ref = @enumFromInt(b.instructions.len);
+ try b.instructions.append(b.gpa, .{
+ .tag = .alloc,
+ .data = .{ .alloc = .{ .size = size, .@"align" = @"align" } },
+ .ty = .ptr,
+ });
+ try b.body.insert(b.gpa, b.alloc_count + b.arg_count + 1, ref);
+ b.alloc_count += 1;
+ return ref;
+ }
+
+ pub fn addInst(b: *Builder, tag: Ir.Inst.Tag, data: Ir.Inst.Data, ty: Interner.Ref) Allocator.Error!Ref {
+ const ref: Ref = @enumFromInt(b.instructions.len);
+ try b.instructions.append(b.gpa, .{ .tag = tag, .data = data, .ty = ty });
+ try b.body.append(b.gpa, ref);
+ return ref;
+ }
+
+ pub fn makeLabel(b: *Builder, name: [*:0]const u8) Allocator.Error!Ref {
+ const ref: Ref = @enumFromInt(b.instructions.len);
+ try b.instructions.append(b.gpa, .{ .tag = .label, .data = .{ .label = name }, .ty = .void });
+ return ref;
+ }
+
+ pub fn addJump(b: *Builder, label: Ref) Allocator.Error!void {
+ _ = try b.addInst(.jmp, .{ .un = label }, .noreturn);
+ }
+
+ pub fn addBranch(b: *Builder, cond: Ref, true_label: Ref, false_label: Ref) Allocator.Error!void {
+ const branch = try b.arena.allocator().create(Ir.Inst.Branch);
+ branch.* = .{
+ .cond = cond,
+ .then = true_label,
+ .@"else" = false_label,
+ };
+ _ = try b.addInst(.branch, .{ .branch = branch }, .noreturn);
+ }
+
+ pub fn addSwitch(b: *Builder, target: Ref, values: []Interner.Ref, labels: []Ref, default: Ref) Allocator.Error!void {
+ assert(values.len == labels.len);
+ const a = b.arena.allocator();
+ const @"switch" = try a.create(Ir.Inst.Switch);
+ @"switch".* = .{
+ .target = target,
+ .cases_len = @intCast(values.len),
+ .case_vals = (try a.dupe(Interner.Ref, values)).ptr,
+ .case_labels = (try a.dupe(Ref, labels)).ptr,
+ .default = default,
+ };
+ _ = try b.addInst(.@"switch", .{ .@"switch" = @"switch" }, .noreturn);
+ }
+
+ pub fn addStore(b: *Builder, ptr: Ref, val: Ref) Allocator.Error!void {
+ _ = try b.addInst(.store, .{ .bin = .{ .lhs = ptr, .rhs = val } }, .void);
+ }
+
+ pub fn addConstant(b: *Builder, val: Value, ty: Interner.Ref) Allocator.Error!Ref {
+ const ref: Ref = @enumFromInt(b.instructions.len);
+ const key: Interner.Key = .{
+ .value = val,
+ };
+ const val_ref = try b.pool.put(b.gpa, key);
+ try b.instructions.append(b.gpa, .{ .tag = .constant, .data = .{
+ .constant = val_ref,
+ }, .ty = ty });
+ return ref;
+ }
+
+ pub fn addPhi(b: *Builder, inputs: []const Inst.Phi.Input, ty: Interner.Ref) Allocator.Error!Ref {
+ const a = b.arena.allocator();
+ const input_refs = try a.alloc(Ref, inputs.len * 2 + 1);
+ input_refs[0] = @enumFromInt(inputs.len);
+ std.mem.copy(Ref, input_refs[1..], std.mem.bytesAsSlice(Ref, std.mem.sliceAsBytes(inputs)));
+
+ return b.addInst(.phi, .{ .phi = .{ .ptr = input_refs.ptr } }, ty);
+ }
+
+ pub fn addSelect(b: *Builder, cond: Ref, then: Ref, @"else": Ref, ty: Interner.Ref) Allocator.Error!Ref {
+ const branch = try b.arena.allocator().create(Ir.Inst.Branch);
+ branch.* = .{
+ .cond = cond,
+ .then = then,
+ .@"else" = @"else",
+ };
+ return b.addInst(.select, .{ .branch = branch }, ty);
+ }
+};
+
+pub const Ref = enum(u32) { none = std.math.maxInt(u32), _ };
+
+pub const Inst = struct {
+ tag: Tag,
+ data: Data,
+ ty: Interner.Ref,
+
+ pub const Tag = enum {
+ // data.constant
+ // not included in blocks
+ constant,
+
+ // data.arg
+ // not included in blocks
+ arg,
+ symbol,
+
+ // data.label
+ label,
+
+ // data.block
+ label_addr,
+ jmp,
+
+ // data.switch
+ @"switch",
+
+ // data.branch
+ branch,
+ select,
+
+ // data.un
+ jmp_val,
+
+ // data.call
+ call,
+
+ // data.alloc
+ alloc,
+
+ // data.phi
+ phi,
+
+ // data.bin
+ store,
+ bit_or,
+ bit_xor,
+ bit_and,
+ bit_shl,
+ bit_shr,
+ cmp_eq,
+ cmp_ne,
+ cmp_lt,
+ cmp_lte,
+ cmp_gt,
+ cmp_gte,
+ add,
+ sub,
+ mul,
+ div,
+ mod,
+
+ // data.un
+ ret,
+ load,
+ bit_not,
+ negate,
+ trunc,
+ zext,
+ sext,
+ };
+
+ pub const Data = union {
+ constant: Interner.Ref,
+ none: void,
+ bin: struct {
+ lhs: Ref,
+ rhs: Ref,
+ },
+ un: Ref,
+ arg: u32,
+ alloc: struct {
+ size: u32,
+ @"align": u32,
+ },
+ @"switch": *Switch,
+ call: *Call,
+ label: [*:0]const u8,
+ branch: *Branch,
+ phi: Phi,
+ };
+
+ pub const Branch = struct {
+ cond: Ref,
+ then: Ref,
+ @"else": Ref,
+ };
+
+ pub const Switch = struct {
+ target: Ref,
+ cases_len: u32,
+ default: Ref,
+ case_vals: [*]Interner.Ref,
+ case_labels: [*]Ref,
+ };
+
+ pub const Call = struct {
+ func: Ref,
+ args_len: u32,
+ args_ptr: [*]Ref,
+
+ pub fn args(c: Call) []Ref {
+ return c.args_ptr[0..c.args_len];
+ }
+ };
+
+ pub const Phi = struct {
+ ptr: [*]Ir.Ref,
+
+ pub const Input = struct {
+ label: Ir.Ref,
+ value: Ir.Ref,
+ };
+
+ pub fn inputs(p: Phi) []Input {
+ const len = @intFromEnum(p.ptr[0]) * 2;
+ const slice = (p.ptr + 1)[0..len];
+ return std.mem.bytesAsSlice(Input, std.mem.sliceAsBytes(slice));
+ }
+ };
+};
+
+pub fn deinit(ir: *Ir, gpa: std.mem.Allocator) void {
+ ir.arena.promote(gpa).deinit();
+ ir.instructions.deinit(gpa);
+ ir.* = undefined;
+}
+
+const util = @import("util.zig");
+const TYPE = util.Color.purple;
+const INST = util.Color.cyan;
+const REF = util.Color.blue;
+const LITERAL = util.Color.green;
+const ATTRIBUTE = util.Color.yellow;
+
+const RefMap = std.AutoArrayHashMap(Ref, void);
+
+pub fn dump(ir: Ir, gpa: Allocator, name: []const u8, color: bool, w: anytype) !void {
+ const tags = ir.instructions.items(.tag);
+ const data = ir.instructions.items(.data);
+
+ var ref_map = RefMap.init(gpa);
+ defer ref_map.deinit();
+
+ var label_map = RefMap.init(gpa);
+ defer label_map.deinit();
+
+ const ret_inst = ir.body.items[ir.body.items.len - 1];
+ const ret_operand = data[@intFromEnum(ret_inst)].un;
+ const ret_ty = ir.instructions.items(.ty)[@intFromEnum(ret_operand)];
+ try ir.writeType(ret_ty, color, w);
+ if (color) util.setColor(REF, w);
+ try w.print(" @{s}", .{name});
+ if (color) util.setColor(.reset, w);
+ try w.writeAll("(");
+
+ var arg_count: u32 = 0;
+ while (true) : (arg_count += 1) {
+ const ref = ir.body.items[arg_count];
+ if (tags[@intFromEnum(ref)] != .arg) break;
+ if (arg_count != 0) try w.writeAll(", ");
+ try ref_map.put(ref, {});
+ try ir.writeRef(&ref_map, ref, color, w);
+ if (color) util.setColor(.reset, w);
+ }
+ try w.writeAll(") {\n");
+ for (ir.body.items[arg_count..]) |ref| {
+ switch (tags[@intFromEnum(ref)]) {
+ .label => try label_map.put(ref, {}),
+ else => {},
+ }
+ }
+
+ for (ir.body.items[arg_count..]) |ref| {
+ const i = @intFromEnum(ref);
+ const tag = tags[i];
+ switch (tag) {
+ .arg, .constant, .symbol => unreachable,
+ .label => {
+ const label_index = label_map.getIndex(ref).?;
+ if (color) util.setColor(REF, w);
+ try w.print("{s}.{d}:\n", .{ data[i].label, label_index });
+ },
+ // .label_val => {
+ // const un = data[i].un;
+ // try w.print(" %{d} = label.{d}\n", .{ i, @intFromEnum(un) });
+ // },
+ .jmp => {
+ const un = data[i].un;
+ if (color) util.setColor(INST, w);
+ try w.writeAll(" jmp ");
+ try ir.writeLabel(&label_map, un, color, w);
+ try w.writeByte('\n');
+ },
+ .branch => {
+ const br = data[i].branch;
+ if (color) util.setColor(INST, w);
+ try w.writeAll(" branch ");
+ try ir.writeRef(&ref_map, br.cond, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(", ");
+ try ir.writeLabel(&label_map, br.then, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(", ");
+ try ir.writeLabel(&label_map, br.@"else", color, w);
+ try w.writeByte('\n');
+ },
+ .select => {
+ const br = data[i].branch;
+ try ir.writeNewRef(&ref_map, ref, color, w);
+ try w.writeAll("select ");
+ try ir.writeRef(&ref_map, br.cond, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(", ");
+ try ir.writeRef(&ref_map, br.then, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(", ");
+ try ir.writeRef(&ref_map, br.@"else", color, w);
+ try w.writeByte('\n');
+ },
+ // .jmp_val => {
+ // const bin = data[i].bin;
+ // try w.print(" %{s} %{d} label.{d}\n", .{ @tagName(tag), @intFromEnum(bin.lhs), @intFromEnum(bin.rhs) });
+ // },
+ .@"switch" => {
+ const @"switch" = data[i].@"switch";
+ if (color) util.setColor(INST, w);
+ try w.writeAll(" switch ");
+ try ir.writeRef(&ref_map, @"switch".target, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(" {");
+ for (@"switch".case_vals[0..@"switch".cases_len], @"switch".case_labels) |val_ref, label_ref| {
+ try w.writeAll("\n ");
+ try ir.writeValue(val_ref, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(" => ");
+ try ir.writeLabel(&label_map, label_ref, color, w);
+ if (color) util.setColor(.reset, w);
+ }
+ if (color) util.setColor(LITERAL, w);
+ try w.writeAll("\n default ");
+ if (color) util.setColor(.reset, w);
+ try w.writeAll("=> ");
+ try ir.writeLabel(&label_map, @"switch".default, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll("\n }\n");
+ },
+ .call => {
+ const call = data[i].call;
+ try ir.writeNewRef(&ref_map, ref, color, w);
+ try w.writeAll("call ");
+ try ir.writeRef(&ref_map, call.func, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll("(");
+ for (call.args(), 0..) |arg, arg_i| {
+ if (arg_i != 0) try w.writeAll(", ");
+ try ir.writeRef(&ref_map, arg, color, w);
+ if (color) util.setColor(.reset, w);
+ }
+ try w.writeAll(")\n");
+ },
+ .alloc => {
+ const alloc = data[i].alloc;
+ try ir.writeNewRef(&ref_map, ref, color, w);
+ try w.writeAll("alloc ");
+ if (color) util.setColor(ATTRIBUTE, w);
+ try w.writeAll("size ");
+ if (color) util.setColor(LITERAL, w);
+ try w.print("{d}", .{alloc.size});
+ if (color) util.setColor(ATTRIBUTE, w);
+ try w.writeAll(" align ");
+ if (color) util.setColor(LITERAL, w);
+ try w.print("{d}", .{alloc.@"align"});
+ try w.writeByte('\n');
+ },
+ .phi => {
+ try ir.writeNewRef(&ref_map, ref, color, w);
+ try w.writeAll("phi");
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(" {");
+ for (data[i].phi.inputs()) |input| {
+ try w.writeAll("\n ");
+ try ir.writeLabel(&label_map, input.label, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(" => ");
+ try ir.writeRef(&ref_map, input.value, color, w);
+ if (color) util.setColor(.reset, w);
+ }
+ if (color) util.setColor(.reset, w);
+ try w.writeAll("\n }\n");
+ },
+ .store => {
+ const bin = data[i].bin;
+ if (color) util.setColor(INST, w);
+ try w.writeAll(" store ");
+ try ir.writeRef(&ref_map, bin.lhs, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(", ");
+ try ir.writeRef(&ref_map, bin.rhs, color, w);
+ try w.writeByte('\n');
+ },
+ .ret => {
+ if (color) util.setColor(INST, w);
+ try w.writeAll(" ret ");
+ if (data[i].un != .none) try ir.writeRef(&ref_map, data[i].un, color, w);
+ try w.writeByte('\n');
+ },
+ .load => {
+ try ir.writeNewRef(&ref_map, ref, color, w);
+ try w.writeAll("load ");
+ try ir.writeRef(&ref_map, data[i].un, color, w);
+ try w.writeByte('\n');
+ },
+ .bit_or,
+ .bit_xor,
+ .bit_and,
+ .bit_shl,
+ .bit_shr,
+ .cmp_eq,
+ .cmp_ne,
+ .cmp_lt,
+ .cmp_lte,
+ .cmp_gt,
+ .cmp_gte,
+ .add,
+ .sub,
+ .mul,
+ .div,
+ .mod,
+ => {
+ const bin = data[i].bin;
+ try ir.writeNewRef(&ref_map, ref, color, w);
+ try w.print("{s} ", .{@tagName(tag)});
+ try ir.writeRef(&ref_map, bin.lhs, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(", ");
+ try ir.writeRef(&ref_map, bin.rhs, color, w);
+ try w.writeByte('\n');
+ },
+ .bit_not,
+ .negate,
+ .trunc,
+ .zext,
+ .sext,
+ => {
+ const un = data[i].un;
+ try ir.writeNewRef(&ref_map, ref, color, w);
+ try w.print("{s} ", .{@tagName(tag)});
+ try ir.writeRef(&ref_map, un, color, w);
+ try w.writeByte('\n');
+ },
+ .label_addr, .jmp_val => {},
+ }
+ }
+ if (color) util.setColor(.reset, w);
+ try w.writeAll("}\n\n");
+}
+
+fn writeType(ir: Ir, ty_ref: Interner.Ref, color: bool, w: anytype) !void {
+ const ty = ir.pool.get(ty_ref);
+ if (color) util.setColor(TYPE, w);
+ switch (ty) {
+ .value => unreachable,
+ .ptr, .noreturn, .void, .func => try w.writeAll(@tagName(ty)),
+ .int => |bits| try w.print("i{d}", .{bits}),
+ .float => |bits| try w.print("f{d}", .{bits}),
+ .array => |info| {
+ try w.print("[{d} * ", .{info.len});
+ try ir.writeType(info.child, false, w);
+ try w.writeByte(']');
+ },
+ .vector => |info| {
+ try w.print("<{d} * ", .{info.len});
+ try ir.writeType(info.child, false, w);
+ try w.writeByte('>');
+ },
+ .record => |info| {
+ // TODO collect into buffer and only print once
+ try w.writeAll("{ ");
+ for (info.elements, 0..) |elem, i| {
+ if (i != 0) try w.writeAll(", ");
+ try ir.writeType(elem, color, w);
+ }
+ try w.writeAll(" }");
+ },
+ }
+}
+
+fn writeValue(ir: Ir, val_ref: Interner.Ref, color: bool, w: anytype) !void {
+ const v = ir.pool.get(val_ref).value;
+ if (color) util.setColor(LITERAL, w);
+ switch (v.tag) {
+ .unavailable => try w.writeAll(" unavailable"),
+ .int => try w.print("{d}", .{v.data.int}),
+ .bytes => try w.print("\"{s}\"", .{v.data.bytes.slice(ir.strings)}),
+ // std.fmt does @as instead of @floatCast
+ .float => try w.print("{d}", .{@as(f64, @floatCast(v.data.float))}),
+ else => try w.print("({s})", .{@tagName(v.tag)}),
+ }
+}
+
+fn writeRef(ir: Ir, ref_map: *RefMap, ref: Ref, color: bool, w: anytype) !void {
+ assert(ref != .none);
+ const index = @intFromEnum(ref);
+ const ty_ref = ir.instructions.items(.ty)[index];
+ if (ir.instructions.items(.tag)[index] == .constant) {
+ try ir.writeType(ty_ref, color, w);
+ const v_ref = ir.instructions.items(.data)[index].constant;
+ try w.writeByte(' ');
+ try ir.writeValue(v_ref, color, w);
+ return;
+ } else if (ir.instructions.items(.tag)[index] == .symbol) {
+ const name = ir.instructions.items(.data)[index].label;
+ try ir.writeType(ty_ref, color, w);
+ if (color) util.setColor(REF, w);
+ try w.print(" @{s}", .{name});
+ return;
+ }
+ try ir.writeType(ty_ref, color, w);
+ if (color) util.setColor(REF, w);
+ const ref_index = ref_map.getIndex(ref).?;
+ try w.print(" %{d}", .{ref_index});
+}
+
+fn writeNewRef(ir: Ir, ref_map: *RefMap, ref: Ref, color: bool, w: anytype) !void {
+ try ref_map.put(ref, {});
+ try w.writeAll(" ");
+ try ir.writeRef(ref_map, ref, color, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeAll(" = ");
+ if (color) util.setColor(INST, w);
+}
+
+fn writeLabel(ir: Ir, label_map: *RefMap, ref: Ref, color: bool, w: anytype) !void {
+ assert(ref != .none);
+ const index = @intFromEnum(ref);
+ const label = ir.instructions.items(.data)[index].label;
+ if (color) util.setColor(REF, w);
+ const label_index = label_map.getIndex(ref).?;
+ try w.print("{s}.{d}", .{ label, label_index });
+}
deps/aro/LangOpts.zig
@@ -0,0 +1,146 @@
+const std = @import("std");
+const DiagnosticTag = @import("Diagnostics.zig").Tag;
+
+const LangOpts = @This();
+
+pub const Compiler = enum {
+ clang,
+ gcc,
+ msvc,
+};
+
+/// The floating-point evaluation method for intermediate results within a single expression
+pub const FPEvalMethod = enum(i8) {
+ /// The evaluation method cannot be determined or is inconsistent for this target.
+ indeterminate = -1,
+ /// Use the type declared in the source
+ source = 0,
+ /// Use double as the floating-point evaluation method for all float expressions narrower than double.
+ double = 1,
+ /// Use long double as the floating-point evaluation method for all float expressions narrower than long double.
+ extended = 2,
+};
+
+pub const Standard = enum {
+ /// ISO C 1990
+ c89,
+ /// ISO C 1990 with amendment 1
+ iso9899,
+ /// ISO C 1990 with GNU extensions
+ gnu89,
+ /// ISO C 1999
+ c99,
+ /// ISO C 1999 with GNU extensions
+ gnu99,
+ /// ISO C 2011
+ c11,
+ /// ISO C 2011 with GNU extensions
+ gnu11,
+ /// ISO C 2017
+ c17,
+ /// Default value if nothing specified; adds the GNU keywords to
+ /// C17 but does not suppress warnings about using GNU extensions
+ default,
+ /// ISO C 2017 with GNU extensions
+ gnu17,
+ /// Working Draft for ISO C2x
+ c2x,
+ /// Working Draft for ISO C2x with GNU extensions
+ gnu2x,
+
+ const NameMap = std.ComptimeStringMap(Standard, .{
+ .{ "c89", .c89 }, .{ "c90", .c89 }, .{ "iso9899:1990", .c89 },
+ .{ "iso9899:199409", .iso9899 }, .{ "gnu89", .gnu89 }, .{ "gnu90", .gnu89 },
+ .{ "c99", .c99 }, .{ "iso9899:1999", .c99 }, .{ "gnu99", .gnu99 },
+ .{ "c11", .c11 }, .{ "iso9899:2011", .c11 }, .{ "gnu11", .gnu11 },
+ .{ "c17", .c17 }, .{ "iso9899:2017", .c17 }, .{ "c18", .c17 },
+ .{ "iso9899:2018", .c17 }, .{ "gnu17", .gnu17 }, .{ "gnu18", .gnu17 },
+ .{ "c2x", .c2x }, .{ "gnu2x", .gnu2x },
+ });
+
+ pub fn atLeast(self: Standard, other: Standard) bool {
+ return @intFromEnum(self) >= @intFromEnum(other);
+ }
+
+ pub fn isGNU(standard: Standard) bool {
+ return switch (standard) {
+ .gnu89, .gnu99, .gnu11, .default, .gnu17, .gnu2x => true,
+ else => false,
+ };
+ }
+
+ pub fn isExplicitGNU(standard: Standard) bool {
+ return standard.isGNU() and standard != .default;
+ }
+
+ /// Value reported by __STDC_VERSION__ macro
+ pub fn StdCVersionMacro(standard: Standard) ?[]const u8 {
+ return switch (standard) {
+ .c89, .gnu89 => null,
+ .iso9899 => "199409L",
+ .c99, .gnu99 => "199901L",
+ .c11, .gnu11 => "201112L",
+ .default, .c17, .gnu17 => "201710L",
+ // todo: subject to change, verify once c23 finalized
+ .c2x, .gnu2x => "202311L",
+ };
+ }
+};
+
+emulate: Compiler = .clang,
+standard: Standard = .default,
+/// -fshort-enums option, makes enums only take up as much space as they need to hold all the values.
+short_enums: bool = false,
+dollars_in_identifiers: bool = true,
+declspec_attrs: bool = false,
+ms_extensions: bool = false,
+/// true or false if digraph support explicitly enabled/disabled with -fdigraphs/-fno-digraphs
+digraphs: ?bool = null,
+/// If set, use the native half type instead of promoting to float
+use_native_half_type: bool = false,
+/// If set, function arguments and return values may be of type __fp16 even if there is no standard ABI for it
+allow_half_args_and_returns: bool = false,
+/// null indicates that the user did not select a value, use target to determine default
+fp_eval_method: ?FPEvalMethod = null,
+/// If set, use specified signedness for `char` instead of the target's default char signedness
+char_signedness_override: ?std.builtin.Signedness = null,
+/// If set, override the default availability of char8_t (by default, enabled in C2X and later; disabled otherwise)
+has_char8_t_override: ?bool = null,
+
+/// Whether to allow GNU-style inline assembly
+gnu_asm: bool = true,
+
+pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {
+ self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;
+}
+
+pub fn enableMSExtensions(self: *LangOpts) void {
+ self.declspec_attrs = true;
+ self.ms_extensions = true;
+}
+
+pub fn disableMSExtensions(self: *LangOpts) void {
+ self.declspec_attrs = false;
+ self.ms_extensions = true;
+}
+
+pub fn hasChar8_T(self: *const LangOpts) bool {
+ return self.has_char8_t_override orelse self.standard.atLeast(.c2x);
+}
+
+pub fn hasDigraphs(self: *const LangOpts) bool {
+ return self.digraphs orelse self.standard.atLeast(.gnu89);
+}
+
+pub fn setEmulatedCompiler(self: *LangOpts, compiler: Compiler) void {
+ self.emulate = compiler;
+ if (compiler == .msvc) self.enableMSExtensions();
+}
+
+pub fn setFpEvalMethod(self: *LangOpts, fp_eval_method: FPEvalMethod) void {
+ self.fp_eval_method = fp_eval_method;
+}
+
+pub fn setCharSignedness(self: *LangOpts, signedness: std.builtin.Signedness) void {
+ self.char_signedness_override = signedness;
+}
deps/aro/lib.zig
@@ -0,0 +1,27 @@
+/// Deprecated
+pub const Codegen = @import("Codegen_legacy.zig");
+pub const CodeGen = @import("CodeGen.zig");
+pub const Compilation = @import("Compilation.zig");
+pub const Diagnostics = @import("Diagnostics.zig");
+pub const Driver = @import("Driver.zig");
+pub const Interner = @import("Interner.zig");
+pub const Ir = @import("Ir.zig");
+pub const Object = @import("Object.zig");
+pub const Parser = @import("Parser.zig");
+pub const Preprocessor = @import("Preprocessor.zig");
+pub const Source = @import("Source.zig");
+pub const Tokenizer = @import("Tokenizer.zig");
+pub const Tree = @import("Tree.zig");
+pub const Type = @import("Type.zig");
+pub const TypeMapper = @import("StringInterner.zig").TypeMapper;
+pub const target_util = @import("target.zig");
+
+pub const version_str = "0.0.0-dev";
+pub const version = @import("std").SemanticVersion.parse(version_str) catch unreachable;
+
+pub const CallingConvention = enum {
+ C,
+ stdcall,
+ thiscall,
+ vectorcall,
+};
deps/aro/number_affixes.zig
@@ -0,0 +1,169 @@
+const std = @import("std");
+const mem = std.mem;
+
+pub const Prefix = enum(u8) {
+ binary = 2,
+ octal = 8,
+ decimal = 10,
+ hex = 16,
+
+ pub fn digitAllowed(prefix: Prefix, c: u8) bool {
+ return switch (c) {
+ '0', '1' => true,
+ '2'...'7' => prefix != .binary,
+ '8'...'9' => prefix == .decimal or prefix == .hex,
+ 'a'...'f', 'A'...'F' => prefix == .hex,
+ else => false,
+ };
+ }
+
+ pub fn fromString(buf: []const u8) Prefix {
+ if (buf.len == 1) return .decimal;
+ // tokenizer enforces that first byte is a decimal digit or period
+ switch (buf[0]) {
+ '.', '1'...'9' => return .decimal,
+ '0' => {},
+ else => unreachable,
+ }
+ switch (buf[1]) {
+ 'x', 'X' => return if (buf.len == 2) .decimal else .hex,
+ 'b', 'B' => return if (buf.len == 2) .decimal else .binary,
+ else => {
+ if (mem.indexOfAny(u8, buf, "eE.")) |_| {
+ // This is a decimal floating point number that happens to start with zero
+ return .decimal;
+ } else if (Suffix.fromString(buf[1..], .int)) |_| {
+ // This is `0` with a valid suffix
+ return .decimal;
+ } else {
+ return .octal;
+ }
+ },
+ }
+ }
+
+ /// Length of this prefix as a string
+ pub fn stringLen(prefix: Prefix) usize {
+ return switch (prefix) {
+ .binary => 2,
+ .octal => 1,
+ .decimal => 0,
+ .hex => 2,
+ };
+ }
+};
+
+pub const Suffix = enum {
+ // zig fmt: off
+
+ // int and imaginary int
+ None, I,
+
+ // unsigned real integers
+ U, UL, ULL,
+
+ // unsigned imaginary integers
+ IU, IUL, IULL,
+
+ // long or long double, real and imaginary
+ L, IL,
+
+ // long long and imaginary long long
+ LL, ILL,
+
+ // float and imaginary float
+ F, IF,
+
+ // _Float16
+ F16,
+
+ // Imaginary _Bitint
+ IWB, IUWB,
+
+ // _Bitint
+ WB, UWB,
+
+ // zig fmt: on
+
+ const Tuple = struct { Suffix, []const []const u8 };
+
+ const IntSuffixes = &[_]Tuple{
+ .{ .U, &.{"U"} },
+ .{ .L, &.{"L"} },
+ .{ .WB, &.{"WB"} },
+ .{ .UL, &.{ "U", "L" } },
+ .{ .UWB, &.{ "U", "WB" } },
+ .{ .LL, &.{"LL"} },
+ .{ .ULL, &.{ "U", "LL" } },
+
+ .{ .I, &.{"I"} },
+
+ .{ .IWB, &.{ "I", "WB" } },
+ .{ .IU, &.{ "I", "U" } },
+ .{ .IL, &.{ "I", "L" } },
+ .{ .IUL, &.{ "I", "U", "L" } },
+ .{ .IUWB, &.{ "I", "U", "WB" } },
+ .{ .ILL, &.{ "I", "LL" } },
+ .{ .IULL, &.{ "I", "U", "LL" } },
+ };
+
+ const FloatSuffixes = &[_]Tuple{
+ .{ .F16, &.{"F16"} },
+ .{ .F, &.{"F"} },
+ .{ .L, &.{"L"} },
+
+ .{ .I, &.{"I"} },
+ .{ .IL, &.{ "I", "L" } },
+ .{ .IF, &.{ "I", "F" } },
+ };
+
+ pub fn fromString(buf: []const u8, suffix_kind: enum { int, float }) ?Suffix {
+ if (buf.len == 0) return .None;
+
+ const suffixes = switch (suffix_kind) {
+ .float => FloatSuffixes,
+ .int => IntSuffixes,
+ };
+ var scratch: [3]u8 = undefined;
+ top: for (suffixes) |candidate| {
+ const tag = candidate[0];
+ const parts = candidate[1];
+ var len: usize = 0;
+ for (parts) |part| len += part.len;
+ if (len != buf.len) continue;
+
+ for (parts) |part| {
+ const lower = std.ascii.lowerString(&scratch, part);
+ if (mem.indexOf(u8, buf, part) == null and mem.indexOf(u8, buf, lower) == null) continue :top;
+ }
+ return tag;
+ }
+ return null;
+ }
+
+ pub fn isImaginary(suffix: Suffix) bool {
+ return switch (suffix) {
+ .I, .IL, .IF, .IU, .IUL, .ILL, .IULL, .IWB, .IUWB => true,
+ .None, .L, .F16, .F, .U, .UL, .LL, .ULL, .WB, .UWB => false,
+ };
+ }
+
+ pub fn isSignedInteger(suffix: Suffix) bool {
+ return switch (suffix) {
+ .None, .L, .LL, .I, .IL, .ILL, .WB, .IWB => true,
+ .U, .UL, .ULL, .IU, .IUL, .IULL, .UWB, .IUWB => false,
+ .F, .IF, .F16 => unreachable,
+ };
+ }
+
+ pub fn signedness(suffix: Suffix) std.builtin.Signedness {
+ return if (suffix.isSignedInteger()) .signed else .unsigned;
+ }
+
+ pub fn isBitInt(suffix: Suffix) bool {
+ return switch (suffix) {
+ .WB, .UWB, .IWB, .IUWB => true,
+ else => false,
+ };
+ }
+};
deps/aro/Object.zig
@@ -0,0 +1,73 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Elf = @import("object/Elf.zig");
+
+const Object = @This();
+
+format: std.Target.ObjectFormat,
+comp: *Compilation,
+
+pub fn create(comp: *Compilation) !*Object {
+ switch (comp.target.ofmt) {
+ .elf => return Elf.create(comp),
+ else => unreachable,
+ }
+}
+
+pub fn deinit(obj: *Object) void {
+ switch (obj.format) {
+ .elf => @fieldParentPtr(Elf, "obj", obj).deinit(),
+ else => unreachable,
+ }
+}
+
+pub const Section = union(enum) {
+ undefined,
+ data,
+ read_only_data,
+ func,
+ strings,
+ custom: []const u8,
+};
+
+pub fn getSection(obj: *Object, section: Section) !*std.ArrayList(u8) {
+ switch (obj.format) {
+ .elf => return @fieldParentPtr(Elf, "obj", obj).getSection(section),
+ else => unreachable,
+ }
+}
+
+pub const SymbolType = enum {
+ func,
+ variable,
+ external,
+};
+
+pub fn declareSymbol(
+ obj: *Object,
+ section: Section,
+ name: ?[]const u8,
+ linkage: std.builtin.GlobalLinkage,
+ @"type": SymbolType,
+ offset: u64,
+ size: u64,
+) ![]const u8 {
+ switch (obj.format) {
+ .elf => return @fieldParentPtr(Elf, "obj", obj).declareSymbol(section, name, linkage, @"type", offset, size),
+ else => unreachable,
+ }
+}
+
+pub fn addRelocation(obj: *Object, name: []const u8, section: Section, address: u64, addend: i64) !void {
+ switch (obj.format) {
+ .elf => return @fieldParentPtr(Elf, "obj", obj).addRelocation(name, section, address, addend),
+ else => unreachable,
+ }
+}
+
+pub fn finish(obj: *Object, file: std.fs.File) !void {
+ switch (obj.format) {
+ .elf => return @fieldParentPtr(Elf, "obj", obj).finish(file),
+ else => unreachable,
+ }
+}
deps/aro/Parser.zig
@@ -0,0 +1,8200 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const assert = std.debug.assert;
+const big = std.math.big;
+const Compilation = @import("Compilation.zig");
+const Source = @import("Source.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const Preprocessor = @import("Preprocessor.zig");
+const Tree = @import("Tree.zig");
+const Token = Tree.Token;
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const NodeList = std.ArrayList(NodeIndex);
+const InitList = @import("InitList.zig");
+const Attribute = @import("Attribute.zig");
+const CharInfo = @import("CharInfo.zig");
+const Value = @import("Value.zig");
+const SymbolStack = @import("SymbolStack.zig");
+const Symbol = SymbolStack.Symbol;
+const record_layout = @import("record_layout.zig");
+const StringId = @import("StringInterner.zig").StringId;
+const number_affixes = @import("number_affixes.zig");
+const NumberPrefix = number_affixes.Prefix;
+const NumberSuffix = number_affixes.Suffix;
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const target_util = @import("target.zig");
+
+const Parser = @This();
+
+const Switch = struct {
+ default: ?TokenIndex = null,
+ ranges: std.ArrayList(Range),
+ ty: Type,
+
+ const Range = struct {
+ first: Value,
+ last: Value,
+ tok: TokenIndex,
+ };
+
+ fn add(
+ self: *Switch,
+ comp: *Compilation,
+ first: Value,
+ last: Value,
+ tok: TokenIndex,
+ ) !?Range {
+ for (self.ranges.items) |range| {
+ if (last.compare(.gte, range.first, self.ty, comp) and first.compare(.lte, range.last, self.ty, comp)) {
+ return range; // They overlap.
+ }
+ }
+ try self.ranges.append(.{
+ .first = first,
+ .last = last,
+ .tok = tok,
+ });
+ return null;
+ }
+};
+
+const Label = union(enum) {
+ unresolved_goto: TokenIndex,
+ label: TokenIndex,
+};
+
+pub const Error = Compilation.Error || error{ParsingFailed};
+
+/// An attribute that has been parsed but not yet validated in its context
+const TentativeAttribute = struct {
+ attr: Attribute,
+ tok: TokenIndex,
+};
+
+/// How the parser handles const int decl references when it is expecting an integer
+/// constant expression.
+const ConstDeclFoldingMode = enum {
+ /// fold const decls as if they were literals
+ fold_const_decls,
+ /// fold const decls as if they were literals and issue GNU extension diagnostic
+ gnu_folding_extension,
+ /// fold const decls as if they were literals and issue VLA diagnostic
+ gnu_vla_folding_extension,
+ /// folding const decls is prohibited; return an unavailable value
+ no_const_decl_folding,
+};
+
+// values from preprocessor
+pp: *Preprocessor,
+comp: *Compilation,
+gpa: mem.Allocator,
+tok_ids: []const Token.Id,
+tok_i: TokenIndex = 0,
+
+// values of the incomplete Tree
+arena: Allocator,
+nodes: Tree.Node.List = .{},
+data: NodeList,
+retained_strings: std.ArrayList(u8),
+value_map: Tree.ValueMap,
+
+// buffers used during compilation
+syms: SymbolStack = .{},
+strings: std.ArrayList(u8),
+labels: std.ArrayList(Label),
+list_buf: NodeList,
+decl_buf: NodeList,
+param_buf: std.ArrayList(Type.Func.Param),
+enum_buf: std.ArrayList(Type.Enum.Field),
+record_buf: std.ArrayList(Type.Record.Field),
+attr_buf: std.MultiArrayList(TentativeAttribute) = .{},
+attr_application_buf: std.ArrayListUnmanaged(Attribute) = .{},
+field_attr_buf: std.ArrayList([]const Attribute),
+/// type name -> variable name location for tentative definitions (top-level defs with thus-far-incomplete types)
+/// e.g. `struct Foo bar;` where `struct Foo` is not defined yet.
+/// The key is the StringId of `Foo` and the value is the TokenIndex of `bar`
+/// Items are removed if the type is subsequently completed with a definition.
+/// We only store the first tentative definition that uses a given type because this map is only used
+/// for issuing an error message, and correcting the first error for a type will fix all of them for that type.
+tentative_defs: std.AutoHashMapUnmanaged(StringId, TokenIndex) = .{},
+
+// configuration and miscellaneous info
+no_eval: bool = false,
+in_macro: bool = false,
+extension_suppressed: bool = false,
+contains_address_of_label: bool = false,
+label_count: u32 = 0,
+const_decl_folding: ConstDeclFoldingMode = .fold_const_decls,
+/// location of first computed goto in function currently being parsed
+/// if a computed goto is used, the function must contain an
+/// address-of-label expression (tracked with contains_address_of_label)
+computed_goto_tok: ?TokenIndex = null,
+
+/// Various variables that are different for each function.
+func: struct {
+ /// null if not in function, will always be plain func, var_args_func or old_style_func
+ ty: ?Type = null,
+ name: TokenIndex = 0,
+ ident: ?Result = null,
+ pretty_ident: ?Result = null,
+} = .{},
+/// Various variables that are different for each record.
+record: struct {
+ // invalid means we're not parsing a record
+ kind: Token.Id = .invalid,
+ flexible_field: ?TokenIndex = null,
+ start: usize = 0,
+ field_attr_start: usize = 0,
+
+ fn addField(r: @This(), p: *Parser, name: StringId, tok: TokenIndex) Error!void {
+ var i = p.record_members.items.len;
+ while (i > r.start) {
+ i -= 1;
+ if (p.record_members.items[i].name == name) {
+ try p.errStr(.duplicate_member, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, p.record_members.items[i].tok);
+ break;
+ }
+ }
+ try p.record_members.append(p.gpa, .{ .name = name, .tok = tok });
+ }
+
+ fn addFieldsFromAnonymous(r: @This(), p: *Parser, ty: Type) Error!void {
+ for (ty.data.record.fields) |f| {
+ if (f.isAnonymousRecord()) {
+ try r.addFieldsFromAnonymous(p, f.ty.canonicalize(.standard));
+ } else if (f.name_tok != 0) {
+ try r.addField(p, f.name, f.name_tok);
+ }
+ }
+ }
+} = .{},
+record_members: std.ArrayListUnmanaged(struct { tok: TokenIndex, name: StringId }) = .{},
+@"switch": ?*Switch = null,
+in_loop: bool = false,
+pragma_pack: ?u8 = null,
+string_ids: struct {
+ declspec_id: StringId,
+ main_id: StringId,
+ file: StringId,
+ jmp_buf: StringId,
+ sigjmp_buf: StringId,
+ ucontext_t: StringId,
+},
+
+fn checkIdentifierCodepoint(comp: *Compilation, codepoint: u21, loc: Source.Location) Compilation.Error!bool {
+ if (codepoint <= 0x7F) return false;
+ var diagnosed = false;
+ if (!CharInfo.isC99IdChar(codepoint)) {
+ try comp.diag.add(.{
+ .tag = .c99_compat,
+ .loc = loc,
+ }, &.{});
+ diagnosed = true;
+ }
+ if (CharInfo.isInvisible(codepoint)) {
+ try comp.diag.add(.{
+ .tag = .unicode_zero_width,
+ .loc = loc,
+ .extra = .{ .actual_codepoint = codepoint },
+ }, &.{});
+ diagnosed = true;
+ }
+ if (CharInfo.homoglyph(codepoint)) |resembles| {
+ try comp.diag.add(.{
+ .tag = .unicode_homoglyph,
+ .loc = loc,
+ .extra = .{ .codepoints = .{ .actual = codepoint, .resembles = resembles } },
+ }, &.{});
+ diagnosed = true;
+ }
+ return diagnosed;
+}
+
+fn eatIdentifier(p: *Parser) !?TokenIndex {
+ switch (p.tok_ids[p.tok_i]) {
+ .identifier => {},
+ .extended_identifier => {
+ const slice = p.tokSlice(p.tok_i);
+ var it = std.unicode.Utf8View.initUnchecked(slice).iterator();
+ var loc = p.pp.tokens.items(.loc)[p.tok_i];
+
+ if (mem.indexOfScalar(u8, slice, '$')) |i| {
+ loc.byte_offset += @intCast(i);
+ try p.comp.diag.add(.{
+ .tag = .dollar_in_identifier_extension,
+ .loc = loc,
+ }, &.{});
+ loc = p.pp.tokens.items(.loc)[p.tok_i];
+ }
+
+ while (it.nextCodepoint()) |c| {
+ if (try checkIdentifierCodepoint(p.comp, c, loc)) break;
+ loc.byte_offset += std.unicode.utf8CodepointSequenceLength(c) catch unreachable;
+ }
+ },
+ else => return null,
+ }
+ p.tok_i += 1;
+
+ // Handle illegal '$' characters in identifiers
+ if (!p.comp.langopts.dollars_in_identifiers) {
+ if (p.tok_ids[p.tok_i] == .invalid and p.tokSlice(p.tok_i)[0] == '$') {
+ try p.err(.dollars_in_identifiers);
+ p.tok_i += 1;
+ return error.ParsingFailed;
+ }
+ }
+
+ return p.tok_i - 1;
+}
+
+fn expectIdentifier(p: *Parser) Error!TokenIndex {
+ const actual = p.tok_ids[p.tok_i];
+ if (actual != .identifier and actual != .extended_identifier) {
+ return p.errExpectedToken(.identifier, actual);
+ }
+
+ return (try p.eatIdentifier()) orelse unreachable;
+}
+
+fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex {
+ assert(id != .identifier and id != .extended_identifier); // use eatIdentifier
+ if (p.tok_ids[p.tok_i] == id) {
+ defer p.tok_i += 1;
+ return p.tok_i;
+ } else return null;
+}
+
+fn expectToken(p: *Parser, expected: Token.Id) Error!TokenIndex {
+ assert(expected != .identifier and expected != .extended_identifier); // use expectIdentifier
+ const actual = p.tok_ids[p.tok_i];
+ if (actual != expected) return p.errExpectedToken(expected, actual);
+ defer p.tok_i += 1;
+ return p.tok_i;
+}
+
+pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 {
+ if (p.tok_ids[tok].lexeme()) |some| return some;
+ const loc = p.pp.tokens.items(.loc)[tok];
+ var tmp_tokenizer = Tokenizer{
+ .buf = p.comp.getSource(loc.id).buf,
+ .comp = p.comp,
+ .index = loc.byte_offset,
+ .source = .generated,
+ };
+ const res = tmp_tokenizer.next();
+ return tmp_tokenizer.buf[res.start..res.end];
+}
+
+fn expectClosing(p: *Parser, opening: TokenIndex, id: Token.Id) Error!void {
+ _ = p.expectToken(id) catch |e| {
+ if (e == error.ParsingFailed) {
+ try p.errTok(switch (id) {
+ .r_paren => .to_match_paren,
+ .r_brace => .to_match_brace,
+ .r_bracket => .to_match_brace,
+ else => unreachable,
+ }, opening);
+ }
+ return e;
+ };
+}
+
+fn errOverflow(p: *Parser, op_tok: TokenIndex, res: Result) !void {
+ if (res.ty.isUnsignedInt(p.comp)) {
+ try p.errExtra(.overflow_unsigned, op_tok, .{ .unsigned = res.val.data.int });
+ } else {
+ try p.errExtra(.overflow_signed, op_tok, .{ .signed = res.val.signExtend(res.ty, p.comp) });
+ }
+}
+
+fn errExpectedToken(p: *Parser, expected: Token.Id, actual: Token.Id) Error {
+ switch (actual) {
+ .invalid => try p.errExtra(.expected_invalid, p.tok_i, .{ .tok_id_expected = expected }),
+ .eof => try p.errExtra(.expected_eof, p.tok_i, .{ .tok_id_expected = expected }),
+ else => try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{
+ .expected = expected,
+ .actual = actual,
+ } }),
+ }
+ return error.ParsingFailed;
+}
+
+pub fn errStr(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, str: []const u8) Compilation.Error!void {
+ @setCold(true);
+ return p.errExtra(tag, tok_i, .{ .str = str });
+}
+
+pub fn errExtra(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, extra: Diagnostics.Message.Extra) Compilation.Error!void {
+ @setCold(true);
+ const tok = p.pp.tokens.get(tok_i);
+ var loc = tok.loc;
+ if (tok_i != 0 and tok.id == .eof) {
+ // if the token is EOF, point at the end of the previous token instead
+ const prev = p.pp.tokens.get(tok_i - 1);
+ loc = prev.loc;
+ loc.byte_offset += @intCast(p.tokSlice(tok_i - 1).len);
+ }
+ try p.comp.diag.add(.{
+ .tag = tag,
+ .loc = loc,
+ .extra = extra,
+ }, tok.expansionSlice());
+}
+
+pub fn errTok(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex) Compilation.Error!void {
+ @setCold(true);
+ return p.errExtra(tag, tok_i, .{ .none = {} });
+}
+
+pub fn err(p: *Parser, tag: Diagnostics.Tag) Compilation.Error!void {
+ @setCold(true);
+ return p.errExtra(tag, p.tok_i, .{ .none = {} });
+}
+
+pub fn todo(p: *Parser, msg: []const u8) Error {
+ try p.errStr(.todo, p.tok_i, msg);
+ return error.ParsingFailed;
+}
+
+pub fn typeStr(p: *Parser, ty: Type) ![]const u8 {
+ if (Type.Builder.fromType(ty).str(p.comp.langopts)) |str| return str;
+ const strings_top = p.strings.items.len;
+ defer p.strings.items.len = strings_top;
+
+ const mapper = p.comp.string_interner.getSlowTypeMapper();
+ try ty.print(mapper, p.comp.langopts, p.strings.writer());
+ return try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+}
+
+pub fn typePairStr(p: *Parser, a: Type, b: Type) ![]const u8 {
+ return p.typePairStrExtra(a, " and ", b);
+}
+
+pub fn typePairStrExtra(p: *Parser, a: Type, msg: []const u8, b: Type) ![]const u8 {
+ const strings_top = p.strings.items.len;
+ defer p.strings.items.len = strings_top;
+
+ try p.strings.append('\'');
+ const mapper = p.comp.string_interner.getSlowTypeMapper();
+ try a.print(mapper, p.comp.langopts, p.strings.writer());
+ try p.strings.append('\'');
+ try p.strings.appendSlice(msg);
+ try p.strings.append('\'');
+ try b.print(mapper, p.comp.langopts, p.strings.writer());
+ try p.strings.append('\'');
+ return try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+}
+
+pub fn floatValueChangedStr(p: *Parser, res: *Result, old_value: f64, int_ty: Type) ![]const u8 {
+ const strings_top = p.strings.items.len;
+ defer p.strings.items.len = strings_top;
+
+ var w = p.strings.writer();
+ const type_pair_str = try p.typePairStrExtra(res.ty, " to ", int_ty);
+ try w.writeAll(type_pair_str);
+ const is_zero = res.val.isZero();
+ const non_zero_str: []const u8 = if (is_zero) "non-zero " else "";
+ if (int_ty.is(.bool)) {
+ try w.print(" changes {s}value from {d} to {}", .{ non_zero_str, old_value, res.val.getBool() });
+ } else if (int_ty.isUnsignedInt(p.comp)) {
+ try w.print(" changes {s}value from {d} to {d}", .{ non_zero_str, old_value, res.val.getInt(u64) });
+ } else {
+ try w.print(" changes {s}value from {d} to {d}", .{ non_zero_str, old_value, res.val.getInt(i64) });
+ }
+
+ return try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+}
+
+fn checkDeprecatedUnavailable(p: *Parser, ty: Type, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {
+ if (ty.getAttribute(.@"error")) |@"error"| {
+ const strings_top = p.strings.items.len;
+ defer p.strings.items.len = strings_top;
+
+ const w = p.strings.writer();
+ const msg_str = p.retainedString(@"error".msg);
+ try w.print("call to '{s}' declared with attribute error: {s}", .{ p.tokSlice(@"error".__name_tok), msg_str });
+ const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+ try p.errStr(.error_attribute, usage_tok, str);
+ }
+ if (ty.getAttribute(.warning)) |warning| {
+ const strings_top = p.strings.items.len;
+ defer p.strings.items.len = strings_top;
+
+ const w = p.strings.writer();
+ const msg_str = p.retainedString(warning.msg);
+ try w.print("call to '{s}' declared with attribute warning: {s}", .{ p.tokSlice(warning.__name_tok), msg_str });
+ const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+ try p.errStr(.warning_attribute, usage_tok, str);
+ }
+ if (ty.getAttribute(.unavailable)) |unavailable| {
+ try p.errDeprecated(.unavailable, usage_tok, unavailable.msg);
+ try p.errStr(.unavailable_note, unavailable.__name_tok, p.tokSlice(decl_tok));
+ return error.ParsingFailed;
+ } else if (ty.getAttribute(.deprecated)) |deprecated| {
+ try p.errDeprecated(.deprecated_declarations, usage_tok, deprecated.msg);
+ try p.errStr(.deprecated_note, deprecated.__name_tok, p.tokSlice(decl_tok));
+ }
+}
+
+/// Returned slice is invalidated if additional strings are added to p.retained_strings
+fn retainedString(p: *Parser, range: Value.ByteRange) []const u8 {
+ return range.slice(p.retained_strings.items);
+}
+
+fn errDeprecated(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, msg: ?Value.ByteRange) Compilation.Error!void {
+ const strings_top = p.strings.items.len;
+ defer p.strings.items.len = strings_top;
+
+ const w = p.strings.writer();
+ try w.print("'{s}' is ", .{p.tokSlice(tok_i)});
+ const reason: []const u8 = switch (tag) {
+ .unavailable => "unavailable",
+ .deprecated_declarations => "deprecated",
+ else => unreachable,
+ };
+ try w.writeAll(reason);
+ if (msg) |m| {
+ const str = p.retainedString(m);
+ try w.print(": {s}", .{str});
+ }
+ const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+ return p.errStr(tag, tok_i, str);
+}
+
+fn addNode(p: *Parser, node: Tree.Node) Allocator.Error!NodeIndex {
+ if (p.in_macro) return .none;
+ const res = p.nodes.len;
+ try p.nodes.append(p.gpa, node);
+ return @enumFromInt(res);
+}
+
+fn addList(p: *Parser, nodes: []const NodeIndex) Allocator.Error!Tree.Node.Range {
+ if (p.in_macro) return Tree.Node.Range{ .start = 0, .end = 0 };
+ const start: u32 = @intCast(p.data.items.len);
+ try p.data.appendSlice(nodes);
+ const end: u32 = @intCast(p.data.items.len);
+ return Tree.Node.Range{ .start = start, .end = end };
+}
+
+fn findLabel(p: *Parser, name: []const u8) ?TokenIndex {
+ for (p.labels.items) |item| {
+ switch (item) {
+ .label => |l| if (mem.eql(u8, p.tokSlice(l), name)) return l,
+ .unresolved_goto => {},
+ }
+ }
+ return null;
+}
+
+fn nodeIs(p: *Parser, node: NodeIndex, tag: Tree.Tag) bool {
+ return p.getNode(node, tag) != null;
+}
+
+fn getNode(p: *Parser, node: NodeIndex, tag: Tree.Tag) ?NodeIndex {
+ var cur = node;
+ const tags = p.nodes.items(.tag);
+ const data = p.nodes.items(.data);
+ while (true) {
+ const cur_tag = tags[@intFromEnum(cur)];
+ if (cur_tag == .paren_expr) {
+ cur = data[@intFromEnum(cur)].un;
+ } else if (cur_tag == tag) {
+ return cur;
+ } else {
+ return null;
+ }
+ }
+}
+
+fn pragma(p: *Parser) Compilation.Error!bool {
+ var found_pragma = false;
+ while (p.eatToken(.keyword_pragma)) |_| {
+ found_pragma = true;
+
+ const name_tok = p.tok_i;
+ const name = p.tokSlice(name_tok);
+
+ const end_idx = mem.indexOfScalarPos(Token.Id, p.tok_ids, p.tok_i, .nl).?;
+ const pragma_len = @as(TokenIndex, @intCast(end_idx)) - p.tok_i;
+ defer p.tok_i += pragma_len + 1; // skip past .nl as well
+ if (p.comp.getPragma(name)) |prag| {
+ try prag.parserCB(p, p.tok_i);
+ }
+ }
+ return found_pragma;
+}
+
+/// Issue errors for top-level definitions whose type was never completed.
+fn diagnoseIncompleteDefinitions(p: *Parser) !void {
+ @setCold(true);
+
+ const node_slices = p.nodes.slice();
+ const tags = node_slices.items(.tag);
+ const tys = node_slices.items(.ty);
+ const data = node_slices.items(.data);
+
+ const err_start = p.comp.diag.list.items.len;
+ for (p.decl_buf.items) |decl_node| {
+ const idx = @intFromEnum(decl_node);
+ switch (tags[idx]) {
+ .struct_forward_decl, .union_forward_decl, .enum_forward_decl => {},
+ else => continue,
+ }
+
+ const ty = tys[idx];
+ const decl_type_name = if (ty.getRecord()) |rec|
+ rec.name
+ else if (ty.get(.@"enum")) |en|
+ en.data.@"enum".name
+ else
+ unreachable;
+
+ const tentative_def_tok = p.tentative_defs.get(decl_type_name) orelse continue;
+ const type_str = try p.typeStr(ty);
+ try p.errStr(.tentative_definition_incomplete, tentative_def_tok, type_str);
+ try p.errStr(.forward_declaration_here, data[idx].decl_ref, type_str);
+ }
+ const errors_added = p.comp.diag.list.items.len - err_start;
+ assert(errors_added == 2 * p.tentative_defs.count()); // Each tentative def should add an error + note
+}
+
+/// root : (decl | assembly ';' | staticAssert)*
+pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {
+ pp.comp.pragmaEvent(.before_parse);
+
+ var arena = std.heap.ArenaAllocator.init(pp.comp.gpa);
+ errdefer arena.deinit();
+ var p = Parser{
+ .pp = pp,
+ .comp = pp.comp,
+ .gpa = pp.comp.gpa,
+ .arena = arena.allocator(),
+ .tok_ids = pp.tokens.items(.id),
+ .strings = std.ArrayList(u8).init(pp.comp.gpa),
+ .retained_strings = std.ArrayList(u8).init(pp.comp.gpa),
+ .value_map = Tree.ValueMap.init(pp.comp.gpa),
+ .data = NodeList.init(pp.comp.gpa),
+ .labels = std.ArrayList(Label).init(pp.comp.gpa),
+ .list_buf = NodeList.init(pp.comp.gpa),
+ .decl_buf = NodeList.init(pp.comp.gpa),
+ .param_buf = std.ArrayList(Type.Func.Param).init(pp.comp.gpa),
+ .enum_buf = std.ArrayList(Type.Enum.Field).init(pp.comp.gpa),
+ .record_buf = std.ArrayList(Type.Record.Field).init(pp.comp.gpa),
+ .field_attr_buf = std.ArrayList([]const Attribute).init(pp.comp.gpa),
+ .string_ids = .{
+ .declspec_id = try pp.comp.intern("__declspec"),
+ .main_id = try pp.comp.intern("main"),
+ .file = try pp.comp.intern("FILE"),
+ .jmp_buf = try pp.comp.intern("jmp_buf"),
+ .sigjmp_buf = try pp.comp.intern("sigjmp_buf"),
+ .ucontext_t = try pp.comp.intern("ucontext_t"),
+ },
+ };
+ errdefer {
+ p.nodes.deinit(pp.comp.gpa);
+ p.retained_strings.deinit();
+ p.value_map.deinit();
+ }
+ defer {
+ p.data.deinit();
+ p.labels.deinit();
+ p.strings.deinit();
+ p.syms.deinit(pp.comp.gpa);
+ p.list_buf.deinit();
+ p.decl_buf.deinit();
+ p.param_buf.deinit();
+ p.enum_buf.deinit();
+ p.record_buf.deinit();
+ p.record_members.deinit(pp.comp.gpa);
+ p.attr_buf.deinit(pp.comp.gpa);
+ p.attr_application_buf.deinit(pp.comp.gpa);
+ p.tentative_defs.deinit(pp.comp.gpa);
+ assert(p.field_attr_buf.items.len == 0);
+ p.field_attr_buf.deinit();
+ }
+
+ // NodeIndex 0 must be invalid
+ _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined });
+
+ {
+ if (p.comp.langopts.hasChar8_T()) {
+ try p.syms.defineTypedef(&p, try p.comp.intern("char8_t"), .{ .specifier = .uchar }, 0, .none);
+ }
+ try p.syms.defineTypedef(&p, try p.comp.intern("__int128_t"), .{ .specifier = .int128 }, 0, .none);
+ try p.syms.defineTypedef(&p, try p.comp.intern("__uint128_t"), .{ .specifier = .uint128 }, 0, .none);
+
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = .{ .specifier = .char };
+ try p.syms.defineTypedef(&p, try p.comp.intern("__builtin_ms_va_list"), .{
+ .specifier = .pointer,
+ .data = .{ .sub_type = elem_ty },
+ }, 0, .none);
+
+ const ty = &pp.comp.types.va_list;
+ try p.syms.defineTypedef(&p, try p.comp.intern("__builtin_va_list"), ty.*, 0, .none);
+
+ if (ty.isArray()) ty.decayArray();
+
+ try p.syms.defineTypedef(&p, try p.comp.intern("__NSConstantString"), pp.comp.types.ns_constant_string.ty, 0, .none);
+ }
+
+ while (p.eatToken(.eof) == null) {
+ if (try p.pragma()) continue;
+ if (try p.parseOrNextDecl(staticAssert)) continue;
+ if (try p.parseOrNextDecl(decl)) continue;
+ if (p.eatToken(.keyword_extension)) |_| {
+ const saved_extension = p.extension_suppressed;
+ defer p.extension_suppressed = saved_extension;
+ p.extension_suppressed = true;
+
+ if (try p.parseOrNextDecl(decl)) continue;
+ switch (p.tok_ids[p.tok_i]) {
+ .semicolon => p.tok_i += 1,
+ .keyword_static_assert,
+ .keyword_c23_static_assert,
+ .keyword_pragma,
+ .keyword_extension,
+ .keyword_asm,
+ .keyword_asm1,
+ .keyword_asm2,
+ => {},
+ else => try p.err(.expected_external_decl),
+ }
+ continue;
+ }
+ if (p.assembly(.global) catch |er| switch (er) {
+ error.ParsingFailed => {
+ p.nextExternDecl();
+ continue;
+ },
+ else => |e| return e,
+ }) |node| {
+ try p.decl_buf.append(node);
+ continue;
+ }
+ if (p.eatToken(.semicolon)) |tok| {
+ try p.errTok(.extra_semi, tok);
+ continue;
+ }
+ try p.err(.expected_external_decl);
+ p.tok_i += 1;
+ }
+ if (p.tentative_defs.count() > 0) {
+ try p.diagnoseIncompleteDefinitions();
+ }
+
+ const root_decls = try p.decl_buf.toOwnedSlice();
+ errdefer pp.comp.gpa.free(root_decls);
+ if (root_decls.len == 0) {
+ try p.errTok(.empty_translation_unit, p.tok_i - 1);
+ }
+ pp.comp.pragmaEvent(.after_parse);
+
+ const data = try p.data.toOwnedSlice();
+ errdefer pp.comp.gpa.free(data);
+ const strings = try p.retained_strings.toOwnedSlice();
+ errdefer pp.comp.gpa.free(strings);
+ return Tree{
+ .comp = pp.comp,
+ .tokens = pp.tokens.slice(),
+ .arena = arena,
+ .generated = pp.comp.generated_buf.items,
+ .nodes = p.nodes.toOwnedSlice(),
+ .data = data,
+ .root_decls = root_decls,
+ .strings = strings,
+ .value_map = p.value_map,
+ };
+}
+
+fn skipToPragmaSentinel(p: *Parser) void {
+ while (true) : (p.tok_i += 1) {
+ if (p.tok_ids[p.tok_i] == .nl) return;
+ if (p.tok_ids[p.tok_i] == .eof) {
+ p.tok_i -= 1;
+ return;
+ }
+ }
+}
+
+fn parseOrNextDecl(p: *Parser, comptime func: fn (*Parser) Error!bool) Compilation.Error!bool {
+ return func(p) catch |er| switch (er) {
+ error.ParsingFailed => {
+ p.nextExternDecl();
+ return true;
+ },
+ else => |e| return e,
+ };
+}
+
+fn nextExternDecl(p: *Parser) void {
+ var parens: u32 = 0;
+ while (true) : (p.tok_i += 1) {
+ switch (p.tok_ids[p.tok_i]) {
+ .l_paren, .l_brace, .l_bracket => parens += 1,
+ .r_paren, .r_brace, .r_bracket => if (parens != 0) {
+ parens -= 1;
+ },
+ .keyword_typedef,
+ .keyword_extern,
+ .keyword_static,
+ .keyword_auto,
+ .keyword_register,
+ .keyword_thread_local,
+ .keyword_c23_thread_local,
+ .keyword_inline,
+ .keyword_inline1,
+ .keyword_inline2,
+ .keyword_noreturn,
+ .keyword_void,
+ .keyword_bool,
+ .keyword_c23_bool,
+ .keyword_char,
+ .keyword_short,
+ .keyword_int,
+ .keyword_long,
+ .keyword_signed,
+ .keyword_unsigned,
+ .keyword_float,
+ .keyword_double,
+ .keyword_complex,
+ .keyword_atomic,
+ .keyword_enum,
+ .keyword_struct,
+ .keyword_union,
+ .keyword_alignas,
+ .keyword_c23_alignas,
+ .identifier,
+ .extended_identifier,
+ .keyword_typeof,
+ .keyword_typeof1,
+ .keyword_typeof2,
+ .keyword_extension,
+ .keyword_bit_int,
+ => if (parens == 0) return,
+ .keyword_pragma => p.skipToPragmaSentinel(),
+ .eof => return,
+ .semicolon => if (parens == 0) {
+ p.tok_i += 1;
+ return;
+ },
+ else => {},
+ }
+ }
+}
+
+fn skipTo(p: *Parser, id: Token.Id) void {
+ var parens: u32 = 0;
+ while (true) : (p.tok_i += 1) {
+ if (p.tok_ids[p.tok_i] == id and parens == 0) {
+ p.tok_i += 1;
+ return;
+ }
+ switch (p.tok_ids[p.tok_i]) {
+ .l_paren, .l_brace, .l_bracket => parens += 1,
+ .r_paren, .r_brace, .r_bracket => if (parens != 0) {
+ parens -= 1;
+ },
+ .keyword_pragma => p.skipToPragmaSentinel(),
+ .eof => return,
+ else => {},
+ }
+ }
+}
+
+/// Called after a typedef is defined
+fn typedefDefined(p: *Parser, name: StringId, ty: Type) void {
+ if (name == p.string_ids.file) {
+ p.comp.types.file = ty;
+ } else if (name == p.string_ids.jmp_buf) {
+ p.comp.types.jmp_buf = ty;
+ } else if (name == p.string_ids.sigjmp_buf) {
+ p.comp.types.sigjmp_buf = ty;
+ } else if (name == p.string_ids.ucontext_t) {
+ p.comp.types.ucontext_t = ty;
+ }
+}
+
+// ====== declarations ======
+
+/// decl
+/// : declSpec (initDeclarator ( ',' initDeclarator)*)? ';'
+/// | declSpec declarator decl* compoundStmt
+fn decl(p: *Parser) Error!bool {
+ _ = try p.pragma();
+ const first_tok = p.tok_i;
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+
+ try p.attributeSpecifier();
+
+ var decl_spec = if (try p.declSpec()) |some| some else blk: {
+ if (p.func.ty != null) {
+ p.tok_i = first_tok;
+ return false;
+ }
+ switch (p.tok_ids[first_tok]) {
+ .asterisk, .l_paren, .identifier, .extended_identifier => {},
+ else => if (p.tok_i != first_tok) {
+ try p.err(.expected_ident_or_l_paren);
+ return error.ParsingFailed;
+ } else return false,
+ }
+ var spec: Type.Builder = .{};
+ break :blk DeclSpec{ .ty = try spec.finish(p) };
+ };
+ if (decl_spec.noreturn) |tok| {
+ const attr = Attribute{ .tag = .noreturn, .args = .{ .noreturn = {} }, .syntax = .keyword };
+ try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = tok });
+ }
+ var init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
+ _ = try p.expectToken(.semicolon);
+ if (decl_spec.ty.is(.@"enum") or
+ (decl_spec.ty.isRecord() and !decl_spec.ty.isAnonymousRecord(p.comp) and
+ !decl_spec.ty.isTypeof())) // we follow GCC and clang's behavior here
+ {
+ const specifier = decl_spec.ty.canonicalize(.standard).specifier;
+ const attrs = p.attr_buf.items(.attr)[attr_buf_top..];
+ const toks = p.attr_buf.items(.tok)[attr_buf_top..];
+ for (attrs, toks) |attr, tok| {
+ try p.errExtra(.ignored_record_attr, tok, .{
+ .ignored_record_attr = .{ .tag = attr.tag, .specifier = switch (specifier) {
+ .@"enum" => .@"enum",
+ .@"struct" => .@"struct",
+ .@"union" => .@"union",
+ else => unreachable,
+ } },
+ });
+ }
+ return true;
+ }
+
+ try p.errTok(.missing_declaration, first_tok);
+ return true;
+ };
+
+ // Check for function definition.
+ if (init_d.d.func_declarator != null and init_d.initializer.node == .none and init_d.d.ty.isFunc()) fn_def: {
+ if (decl_spec.auto_type) |tok_i| {
+ try p.errStr(.auto_type_not_allowed, tok_i, "function return type");
+ return error.ParsingFailed;
+ }
+
+ switch (p.tok_ids[p.tok_i]) {
+ .comma, .semicolon => break :fn_def,
+ .l_brace => {},
+ else => if (init_d.d.old_style_func == null) {
+ try p.err(.expected_fn_body);
+ return true;
+ },
+ }
+ if (p.func.ty != null) try p.err(.func_not_in_root);
+
+ const node = try p.addNode(undefined); // reserve space
+ const interned_declarator_name = try p.comp.intern(p.tokSlice(init_d.d.name));
+ try p.syms.defineSymbol(p, interned_declarator_name, init_d.d.ty, init_d.d.name, node, .{}, false);
+
+ const func = p.func;
+ p.func = .{
+ .ty = init_d.d.ty,
+ .name = init_d.d.name,
+ };
+ if (interned_declarator_name == p.string_ids.main_id and !init_d.d.ty.returnType().is(.int)) {
+ try p.errTok(.main_return_type, init_d.d.name);
+ }
+ defer p.func = func;
+
+ try p.syms.pushScope(p);
+ defer p.syms.popScope();
+
+ // Collect old style parameter declarations.
+ if (init_d.d.old_style_func != null) {
+ const attrs = init_d.d.ty.getAttributes();
+ var base_ty = if (init_d.d.ty.specifier == .attributed) init_d.d.ty.elemType() else init_d.d.ty;
+ base_ty.specifier = .func;
+ init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);
+
+ const param_buf_top = p.param_buf.items.len;
+ defer p.param_buf.items.len = param_buf_top;
+
+ param_loop: while (true) {
+ const param_decl_spec = (try p.declSpec()) orelse break;
+ if (p.eatToken(.semicolon)) |semi| {
+ try p.errTok(.missing_declaration, semi);
+ continue :param_loop;
+ }
+
+ while (true) {
+ const attr_buf_top_declarator = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top_declarator;
+
+ var d = (try p.declarator(param_decl_spec.ty, .normal)) orelse {
+ try p.errTok(.missing_declaration, first_tok);
+ _ = try p.expectToken(.semicolon);
+ continue :param_loop;
+ };
+ try p.attributeSpecifier();
+
+ if (d.ty.hasIncompleteSize() and !d.ty.is(.void)) try p.errStr(.parameter_incomplete_ty, d.name, try p.typeStr(d.ty));
+ if (d.ty.isFunc()) {
+ // Params declared as functions are converted to function pointers.
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = d.ty;
+ d.ty = Type{
+ .specifier = .pointer,
+ .data = .{ .sub_type = elem_ty },
+ };
+ } else if (d.ty.isArray()) {
+ // params declared as arrays are converted to pointers
+ d.ty.decayArray();
+ } else if (d.ty.is(.void)) {
+ try p.errTok(.invalid_void_param, d.name);
+ }
+
+ // find and correct parameter types
+ // TODO check for missing declarations and redefinitions
+ const name_str = p.tokSlice(d.name);
+ const interned_name = try p.comp.intern(name_str);
+ for (init_d.d.ty.params()) |*param| {
+ if (param.name == interned_name) {
+ param.ty = d.ty;
+ break;
+ }
+ } else {
+ try p.errStr(.parameter_missing, d.name, name_str);
+ }
+ d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param);
+
+ // bypass redefinition check to avoid duplicate errors
+ try p.syms.syms.append(p.gpa, .{
+ .kind = .def,
+ .name = interned_name,
+ .tok = d.name,
+ .ty = d.ty,
+ .val = .{},
+ });
+ if (p.eatToken(.comma) == null) break;
+ }
+ _ = try p.expectToken(.semicolon);
+ }
+ } else {
+ for (init_d.d.ty.params()) |param| {
+ if (param.ty.hasUnboundVLA()) try p.errTok(.unbound_vla, param.name_tok);
+ if (param.ty.hasIncompleteSize() and !param.ty.is(.void) and param.ty.specifier != .invalid) try p.errStr(.parameter_incomplete_ty, param.name_tok, try p.typeStr(param.ty));
+
+ if (param.name == .empty) {
+ try p.errTok(.omitting_parameter_name, param.name_tok);
+ continue;
+ }
+
+ // bypass redefinition check to avoid duplicate errors
+ try p.syms.syms.append(p.gpa, .{
+ .kind = .def,
+ .name = param.name,
+ .tok = param.name_tok,
+ .ty = param.ty,
+ .val = .{},
+ });
+ }
+ }
+
+ const body = (try p.compoundStmt(true, null)) orelse {
+ assert(init_d.d.old_style_func != null);
+ try p.err(.expected_fn_body);
+ return true;
+ };
+ p.nodes.set(@intFromEnum(node), .{
+ .ty = init_d.d.ty,
+ .tag = try decl_spec.validateFnDef(p),
+ .data = .{ .decl = .{ .name = init_d.d.name, .node = body } },
+ });
+ try p.decl_buf.append(node);
+
+ // check gotos
+ if (func.ty == null) {
+ for (p.labels.items) |item| {
+ if (item == .unresolved_goto)
+ try p.errStr(.undeclared_label, item.unresolved_goto, p.tokSlice(item.unresolved_goto));
+ }
+ if (p.computed_goto_tok) |goto_tok| {
+ if (!p.contains_address_of_label) try p.errTok(.invalid_computed_goto, goto_tok);
+ }
+ p.labels.items.len = 0;
+ p.label_count = 0;
+ p.contains_address_of_label = false;
+ p.computed_goto_tok = null;
+ }
+ return true;
+ }
+
+ // Declare all variable/typedef declarators.
+ while (true) {
+ if (init_d.d.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
+ const tag = try decl_spec.validate(p, &init_d.d.ty, init_d.initializer.node != .none);
+
+ const node = try p.addNode(.{ .ty = init_d.d.ty, .tag = tag, .data = .{
+ .decl = .{ .name = init_d.d.name, .node = init_d.initializer.node },
+ } });
+ try p.decl_buf.append(node);
+
+ const interned_name = try p.comp.intern(p.tokSlice(init_d.d.name));
+ if (decl_spec.storage_class == .typedef) {
+ try p.syms.defineTypedef(p, interned_name, init_d.d.ty, init_d.d.name, node);
+ p.typedefDefined(interned_name, init_d.d.ty);
+ } else if (init_d.initializer.node != .none or
+ (p.func.ty != null and decl_spec.storage_class != .@"extern"))
+ {
+ // TODO validate global variable/constexpr initializer comptime known
+ try p.syms.defineSymbol(
+ p,
+ interned_name,
+ init_d.d.ty,
+ init_d.d.name,
+ node,
+ if (init_d.d.ty.isConst() or decl_spec.constexpr != null) init_d.initializer.val else .{},
+ decl_spec.constexpr != null,
+ );
+ } else {
+ try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, node);
+ }
+
+ if (p.eatToken(.comma) == null) break;
+
+ if (decl_spec.auto_type) |tok_i| try p.errTok(.auto_type_requires_single_declarator, tok_i);
+
+ init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
+ try p.err(.expected_ident_or_l_paren);
+ continue;
+ };
+ }
+
+ _ = try p.expectToken(.semicolon);
+ return true;
+}
+
+fn staticAssertMessage(p: *Parser, cond_node: NodeIndex, message: Result) !?[]const u8 {
+ const cond_tag = p.nodes.items(.tag)[@intFromEnum(cond_node)];
+ if (cond_tag != .builtin_types_compatible_p and message.node == .none) return null;
+
+ var buf = std.ArrayList(u8).init(p.gpa);
+ defer buf.deinit();
+
+ if (cond_tag == .builtin_types_compatible_p) {
+ const mapper = p.comp.string_interner.getSlowTypeMapper();
+ const data = p.nodes.items(.data)[@intFromEnum(cond_node)].bin;
+
+ try buf.appendSlice("'__builtin_types_compatible_p(");
+
+ const lhs_ty = p.nodes.items(.ty)[@intFromEnum(data.lhs)];
+ try lhs_ty.print(mapper, p.comp.langopts, buf.writer());
+ try buf.appendSlice(", ");
+
+ const rhs_ty = p.nodes.items(.ty)[@intFromEnum(data.rhs)];
+ try rhs_ty.print(mapper, p.comp.langopts, buf.writer());
+
+ try buf.appendSlice(")'");
+ }
+ if (message.node != .none) {
+ if (buf.items.len > 0) {
+ try buf.append(' ');
+ }
+ const data = message.val.data.bytes;
+ try buf.ensureUnusedCapacity(data.len());
+ try Tree.dumpStr(
+ p.retained_strings.items,
+ data,
+ p.nodes.items(.tag)[@intFromEnum(message.node)],
+ buf.writer(),
+ );
+ }
+ return try p.comp.diag.arena.allocator().dupe(u8, buf.items);
+}
+
+/// staticAssert
+/// : keyword_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
+/// | keyword_c23_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
+fn staticAssert(p: *Parser) Error!bool {
+ const static_assert = p.eatToken(.keyword_static_assert) orelse p.eatToken(.keyword_c23_static_assert) orelse return false;
+ const l_paren = try p.expectToken(.l_paren);
+ const res_token = p.tok_i;
+ var res = try p.constExpr(.gnu_folding_extension);
+ const res_node = res.node;
+ const str = if (p.eatToken(.comma) != null)
+ switch (p.tok_ids[p.tok_i]) {
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ => try p.stringLiteral(),
+ else => {
+ try p.err(.expected_str_literal);
+ return error.ParsingFailed;
+ },
+ }
+ else
+ Result{};
+ try p.expectClosing(l_paren, .r_paren);
+ _ = try p.expectToken(.semicolon);
+ if (str.node == .none) {
+ try p.errTok(.static_assert_missing_message, static_assert);
+ try p.errStr(.pre_c2x_compat, static_assert, "'_Static_assert' with no message");
+ }
+
+ // Array will never be zero; a value of zero for a pointer is a null pointer constant
+ if ((res.ty.isArray() or res.ty.isPtr()) and !res.val.isZero()) {
+ const err_start = p.comp.diag.list.items.len;
+ try p.errTok(.const_decl_folded, res_token);
+ if (res.ty.isPtr() and err_start != p.comp.diag.list.items.len) {
+ // Don't show the note if the .const_decl_folded diagnostic was not added
+ try p.errTok(.constant_expression_conversion_not_allowed, res_token);
+ }
+ }
+ try res.boolCast(p, .{ .specifier = .bool }, res_token);
+ if (res.val.tag == .unavailable) {
+ if (res.ty.specifier != .invalid) {
+ try p.errTok(.static_assert_not_constant, res_token);
+ }
+ } else {
+ if (!res.val.getBool()) {
+ if (try p.staticAssertMessage(res_node, str)) |message| {
+ try p.errStr(.static_assert_failure_message, static_assert, message);
+ } else {
+ try p.errTok(.static_assert_failure, static_assert);
+ }
+ }
+ }
+
+ const node = try p.addNode(.{
+ .tag = .static_assert,
+ .data = .{ .bin = .{
+ .lhs = res.node,
+ .rhs = str.node,
+ } },
+ });
+ try p.decl_buf.append(node);
+ return true;
+}
+
+pub const DeclSpec = struct {
+ storage_class: union(enum) {
+ auto: TokenIndex,
+ @"extern": TokenIndex,
+ register: TokenIndex,
+ static: TokenIndex,
+ typedef: TokenIndex,
+ none,
+ } = .none,
+ thread_local: ?TokenIndex = null,
+ constexpr: ?TokenIndex = null,
+ @"inline": ?TokenIndex = null,
+ noreturn: ?TokenIndex = null,
+ auto_type: ?TokenIndex = null,
+ ty: Type,
+
+ fn validateParam(d: DeclSpec, p: *Parser, ty: *Type) Error!void {
+ switch (d.storage_class) {
+ .none => {},
+ .register => ty.qual.register = true,
+ .auto, .@"extern", .static, .typedef => |tok_i| try p.errTok(.invalid_storage_on_param, tok_i),
+ }
+ if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
+ if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
+ if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
+ if (d.constexpr) |tok_i| try p.errTok(.invalid_storage_on_param, tok_i);
+ if (d.auto_type) |tok_i| {
+ try p.errStr(.auto_type_not_allowed, tok_i, "function prototype");
+ ty.* = Type.invalid;
+ }
+ }
+
+ fn validateFnDef(d: DeclSpec, p: *Parser) Error!Tree.Tag {
+ switch (d.storage_class) {
+ .none, .@"extern", .static => {},
+ .auto, .register, .typedef => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
+ }
+ if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
+ if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
+
+ const is_static = d.storage_class == .static;
+ const is_inline = d.@"inline" != null;
+ if (is_static) {
+ if (is_inline) return .inline_static_fn_def;
+ return .static_fn_def;
+ } else {
+ if (is_inline) return .inline_fn_def;
+ return .fn_def;
+ }
+ }
+
+ fn validate(d: DeclSpec, p: *Parser, ty: *Type, has_init: bool) Error!Tree.Tag {
+ const is_static = d.storage_class == .static;
+ if (ty.isFunc() and d.storage_class != .typedef) {
+ switch (d.storage_class) {
+ .none, .@"extern" => {},
+ .static => |tok_i| if (p.func.ty != null) try p.errTok(.static_func_not_global, tok_i),
+ .typedef => unreachable,
+ .auto, .register => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
+ }
+ if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
+ if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
+
+ const is_inline = d.@"inline" != null;
+ if (is_static) {
+ if (is_inline) return .inline_static_fn_proto;
+ return .static_fn_proto;
+ } else {
+ if (is_inline) return .inline_fn_proto;
+ return .fn_proto;
+ }
+ } else {
+ if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
+ // TODO move to attribute validation
+ if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
+ switch (d.storage_class) {
+ .auto, .register => if (p.func.ty == null) try p.err(.illegal_storage_on_global),
+ .typedef => return .typedef,
+ else => {},
+ }
+ ty.qual.register = d.storage_class == .register;
+
+ const is_extern = d.storage_class == .@"extern" and !has_init;
+ if (d.thread_local != null) {
+ if (is_static) return .threadlocal_static_var;
+ if (is_extern) return .threadlocal_extern_var;
+ return .threadlocal_var;
+ } else {
+ if (is_static) return .static_var;
+ if (is_extern) return .extern_var;
+ return .@"var";
+ }
+ }
+ }
+};
+
+/// typeof
+/// : keyword_typeof '(' typeName ')'
+/// | keyword_typeof '(' expr ')'
+fn typeof(p: *Parser) Error!?Type {
+ switch (p.tok_ids[p.tok_i]) {
+ .keyword_typeof, .keyword_typeof1, .keyword_typeof2 => p.tok_i += 1,
+ else => return null,
+ }
+ const l_paren = try p.expectToken(.l_paren);
+ if (try p.typeName()) |ty| {
+ try p.expectClosing(l_paren, .r_paren);
+ const typeof_ty = try p.arena.create(Type);
+ typeof_ty.* = .{
+ .data = ty.data,
+ .qual = ty.qual.inheritFromTypeof(),
+ .specifier = ty.specifier,
+ };
+
+ return Type{
+ .data = .{ .sub_type = typeof_ty },
+ .specifier = .typeof_type,
+ };
+ }
+ const typeof_expr = try p.parseNoEval(expr);
+ try typeof_expr.expect(p);
+ try p.expectClosing(l_paren, .r_paren);
+ // Special case nullptr_t since it's defined as typeof(nullptr)
+ if (typeof_expr.ty.is(.nullptr_t)) {
+ return Type{ .specifier = .nullptr_t, .qual = typeof_expr.ty.qual.inheritFromTypeof() };
+ }
+
+ const inner = try p.arena.create(Type.Expr);
+ inner.* = .{
+ .node = typeof_expr.node,
+ .ty = .{
+ .data = typeof_expr.ty.data,
+ .qual = typeof_expr.ty.qual.inheritFromTypeof(),
+ .specifier = typeof_expr.ty.specifier,
+ },
+ };
+
+ return Type{
+ .data = .{ .expr = inner },
+ .specifier = .typeof_expr,
+ };
+}
+
+/// declSpec: (storageClassSpec | typeSpec | typeQual | funcSpec | alignSpec)+
+/// storageClassSpec:
+/// : keyword_typedef
+/// | keyword_extern
+/// | keyword_static
+/// | keyword_threadlocal
+/// | keyword_auto
+/// | keyword_register
+/// funcSpec : keyword_inline | keyword_noreturn
+fn declSpec(p: *Parser) Error!?DeclSpec {
+ var d: DeclSpec = .{ .ty = .{ .specifier = undefined } };
+ var spec: Type.Builder = .{};
+
+ const start = p.tok_i;
+ while (true) {
+ if (try p.typeSpec(&spec)) continue;
+ const id = p.tok_ids[p.tok_i];
+ switch (id) {
+ .keyword_typedef,
+ .keyword_extern,
+ .keyword_static,
+ .keyword_auto,
+ .keyword_register,
+ => {
+ if (d.storage_class != .none) {
+ try p.errStr(.multiple_storage_class, p.tok_i, @tagName(d.storage_class));
+ return error.ParsingFailed;
+ }
+ if (d.thread_local != null) {
+ switch (id) {
+ .keyword_extern, .keyword_static => {},
+ else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
+ }
+ if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+ }
+ if (d.constexpr != null) {
+ switch (id) {
+ .keyword_auto, .keyword_register, .keyword_static => {},
+ else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
+ }
+ if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+ }
+ switch (id) {
+ .keyword_typedef => d.storage_class = .{ .typedef = p.tok_i },
+ .keyword_extern => d.storage_class = .{ .@"extern" = p.tok_i },
+ .keyword_static => d.storage_class = .{ .static = p.tok_i },
+ .keyword_auto => d.storage_class = .{ .auto = p.tok_i },
+ .keyword_register => d.storage_class = .{ .register = p.tok_i },
+ else => unreachable,
+ }
+ },
+ .keyword_thread_local,
+ .keyword_c23_thread_local,
+ => {
+ if (d.thread_local != null) {
+ try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
+ }
+ if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+ switch (d.storage_class) {
+ .@"extern", .none, .static => {},
+ else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
+ }
+ d.thread_local = p.tok_i;
+ },
+ .keyword_constexpr => {
+ if (d.constexpr != null) {
+ try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
+ }
+ if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+ switch (d.storage_class) {
+ .auto, .register, .none, .static => {},
+ else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
+ }
+ d.constexpr = p.tok_i;
+ },
+ .keyword_inline, .keyword_inline1, .keyword_inline2 => {
+ if (d.@"inline" != null) {
+ try p.errStr(.duplicate_decl_spec, p.tok_i, "inline");
+ }
+ d.@"inline" = p.tok_i;
+ },
+ .keyword_noreturn => {
+ if (d.noreturn != null) {
+ try p.errStr(.duplicate_decl_spec, p.tok_i, "_Noreturn");
+ }
+ d.noreturn = p.tok_i;
+ },
+ else => break,
+ }
+ p.tok_i += 1;
+ }
+
+ if (p.tok_i == start) return null;
+
+ d.ty = try spec.finish(p);
+ d.auto_type = spec.auto_type_tok;
+ return d;
+}
+
+const InitDeclarator = struct { d: Declarator, initializer: Result = .{} };
+
+/// attribute
+/// : attrIdentifier
+/// | attrIdentifier '(' identifier ')'
+/// | attrIdentifier '(' identifier (',' expr)+ ')'
+/// | attrIdentifier '(' (expr (',' expr)*)? ')'
+fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?TentativeAttribute {
+ const name_tok = p.tok_i;
+ switch (p.tok_ids[p.tok_i]) {
+ .keyword_const, .keyword_const1, .keyword_const2 => p.tok_i += 1,
+ else => _ = try p.expectIdentifier(),
+ }
+ const name = p.tokSlice(name_tok);
+
+ const attr = Attribute.fromString(kind, namespace, name) orelse {
+ const tag: Diagnostics.Tag = if (kind == .declspec) .declspec_attr_not_supported else .unknown_attribute;
+ try p.errStr(tag, name_tok, name);
+ if (p.eatToken(.l_paren)) |_| p.skipTo(.r_paren);
+ return null;
+ };
+
+ const required_count = Attribute.requiredArgCount(attr);
+ var arguments = Attribute.initArguments(attr, name_tok);
+ var arg_idx: u32 = 0;
+
+ switch (p.tok_ids[p.tok_i]) {
+ .comma, .r_paren => {}, // will be consumed in attributeList
+ .l_paren => blk: {
+ p.tok_i += 1;
+ if (p.eatToken(.r_paren)) |_| break :blk;
+
+ if (Attribute.wantsIdentEnum(attr)) {
+ if (try p.eatIdentifier()) |ident| {
+ if (Attribute.diagnoseIdent(attr, &arguments, p.tokSlice(ident))) |msg| {
+ try p.errExtra(msg.tag, ident, msg.extra);
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ }
+ } else {
+ try p.errExtra(.attribute_requires_identifier, name_tok, .{ .str = name });
+ return error.ParsingFailed;
+ }
+ } else {
+ const arg_start = p.tok_i;
+ var first_expr = try p.assignExpr();
+ try first_expr.expect(p);
+ if (p.diagnose(attr, &arguments, arg_idx, first_expr)) |msg| {
+ try p.errExtra(msg.tag, arg_start, msg.extra);
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ }
+ }
+ arg_idx += 1;
+ while (p.eatToken(.r_paren) == null) : (arg_idx += 1) {
+ _ = try p.expectToken(.comma);
+
+ const arg_start = p.tok_i;
+ var arg_expr = try p.assignExpr();
+ try arg_expr.expect(p);
+ if (p.diagnose(attr, &arguments, arg_idx, arg_expr)) |msg| {
+ try p.errExtra(msg.tag, arg_start, msg.extra);
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ }
+ }
+ },
+ else => {},
+ }
+ if (arg_idx < required_count) {
+ try p.errExtra(.attribute_not_enough_args, name_tok, .{ .attr_arg_count = .{ .attribute = attr, .expected = required_count } });
+ return error.ParsingFailed;
+ }
+ return TentativeAttribute{ .attr = .{ .tag = attr, .args = arguments, .syntax = kind.toSyntax() }, .tok = name_tok };
+}
+
+fn diagnose(p: *Parser, attr: Attribute.Tag, arguments: *Attribute.Arguments, arg_idx: u32, res: Result) ?Diagnostics.Message {
+ if (Attribute.wantsAlignment(attr, arg_idx)) {
+ return Attribute.diagnoseAlignment(attr, arguments, arg_idx, res.val, res.ty, p.comp);
+ }
+ const node = p.nodes.get(@intFromEnum(res.node));
+ return Attribute.diagnose(attr, arguments, arg_idx, res.val, node, p.retained_strings.items);
+}
+
+/// attributeList : (attribute (',' attribute)*)?
+fn gnuAttributeList(p: *Parser) Error!void {
+ if (p.tok_ids[p.tok_i] == .r_paren) return;
+
+ if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
+ while (p.tok_ids[p.tok_i] != .r_paren) {
+ _ = try p.expectToken(.comma);
+ if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
+ }
+}
+
+fn c2xAttributeList(p: *Parser) Error!void {
+ while (p.tok_ids[p.tok_i] != .r_bracket) {
+ var namespace_tok = try p.expectIdentifier();
+ var namespace: ?[]const u8 = null;
+ if (p.eatToken(.colon_colon)) |_| {
+ namespace = p.tokSlice(namespace_tok);
+ } else {
+ p.tok_i -= 1;
+ }
+ if (try p.attribute(.c2x, namespace)) |attr| try p.attr_buf.append(p.gpa, attr);
+ _ = p.eatToken(.comma);
+ }
+}
+
+fn msvcAttributeList(p: *Parser) Error!void {
+ while (p.tok_ids[p.tok_i] != .r_paren) {
+ if (try p.attribute(.declspec, null)) |attr| try p.attr_buf.append(p.gpa, attr);
+ _ = p.eatToken(.comma);
+ }
+}
+
+fn c2xAttribute(p: *Parser) !bool {
+ if (!p.comp.langopts.standard.atLeast(.c2x)) return false;
+ const bracket1 = p.eatToken(.l_bracket) orelse return false;
+ const bracket2 = p.eatToken(.l_bracket) orelse {
+ p.tok_i -= 1;
+ return false;
+ };
+
+ try p.c2xAttributeList();
+
+ _ = try p.expectClosing(bracket2, .r_bracket);
+ _ = try p.expectClosing(bracket1, .r_bracket);
+
+ return true;
+}
+
+fn msvcAttribute(p: *Parser) !bool {
+ _ = p.eatToken(.keyword_declspec) orelse return false;
+ const l_paren = try p.expectToken(.l_paren);
+ try p.msvcAttributeList();
+ _ = try p.expectClosing(l_paren, .r_paren);
+
+ return true;
+}
+
+fn gnuAttribute(p: *Parser) !bool {
+ switch (p.tok_ids[p.tok_i]) {
+ .keyword_attribute1, .keyword_attribute2 => p.tok_i += 1,
+ else => return false,
+ }
+ const paren1 = try p.expectToken(.l_paren);
+ const paren2 = try p.expectToken(.l_paren);
+
+ try p.gnuAttributeList();
+
+ _ = try p.expectClosing(paren2, .r_paren);
+ _ = try p.expectClosing(paren1, .r_paren);
+ return true;
+}
+
+fn attributeSpecifier(p: *Parser) Error!void {
+ return attributeSpecifierExtra(p, null);
+}
+
+/// attributeSpecifier : (keyword_attribute '( '(' attributeList ')' ')')*
+fn attributeSpecifierExtra(p: *Parser, declarator_name: ?TokenIndex) Error!void {
+ while (true) {
+ if (try p.gnuAttribute()) continue;
+ if (try p.c2xAttribute()) continue;
+ const maybe_declspec_tok = p.tok_i;
+ const attr_buf_top = p.attr_buf.len;
+ if (try p.msvcAttribute()) {
+ if (declarator_name) |name_tok| {
+ try p.errTok(.declspec_not_allowed_after_declarator, maybe_declspec_tok);
+ try p.errTok(.declarator_name_tok, name_tok);
+ p.attr_buf.len = attr_buf_top;
+ }
+ continue;
+ }
+ break;
+ }
+}
+
+/// initDeclarator : declarator assembly? attributeSpecifier? ('=' initializer)?
+fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?InitDeclarator {
+ const this_attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = this_attr_buf_top;
+
+ var init_d = InitDeclarator{
+ .d = (try p.declarator(decl_spec.ty, .normal)) orelse return null,
+ };
+
+ try p.attributeSpecifierExtra(init_d.d.name);
+ _ = try p.assembly(.decl_label);
+ try p.attributeSpecifierExtra(init_d.d.name);
+
+ var apply_var_attributes = false;
+ if (decl_spec.storage_class == .typedef) {
+ if (decl_spec.auto_type) |tok_i| {
+ try p.errStr(.auto_type_not_allowed, tok_i, "typedef");
+ return error.ParsingFailed;
+ }
+ init_d.d.ty = try Attribute.applyTypeAttributes(p, init_d.d.ty, attr_buf_top, null);
+ } else if (init_d.d.ty.isFunc()) {
+ init_d.d.ty = try Attribute.applyFunctionAttributes(p, init_d.d.ty, attr_buf_top);
+ } else {
+ apply_var_attributes = true;
+ }
+
+ if (p.eatToken(.equal)) |eq| init: {
+ if (decl_spec.storage_class == .typedef or init_d.d.func_declarator != null) {
+ try p.errTok(.illegal_initializer, eq);
+ } else if (init_d.d.ty.is(.variable_len_array)) {
+ try p.errTok(.vla_init, eq);
+ } else if (decl_spec.storage_class == .@"extern") {
+ try p.err(.extern_initializer);
+ decl_spec.storage_class = .none;
+ }
+
+ if (init_d.d.ty.hasIncompleteSize() and !init_d.d.ty.is(.incomplete_array)) {
+ try p.errStr(.variable_incomplete_ty, init_d.d.name, try p.typeStr(init_d.d.ty));
+ return error.ParsingFailed;
+ }
+
+ try p.syms.pushScope(p);
+ defer p.syms.popScope();
+
+ const interned_name = try p.comp.intern(p.tokSlice(init_d.d.name));
+ try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, .none);
+ var init_list_expr = try p.initializer(init_d.d.ty);
+ init_d.initializer = init_list_expr;
+ if (!init_list_expr.ty.isArray()) break :init;
+ if (init_d.d.ty.specifier == .incomplete_array) {
+ // Modifying .data is exceptionally allowed for .incomplete_array.
+ init_d.d.ty.data.array.len = init_list_expr.ty.arrayLen() orelse break :init;
+ init_d.d.ty.specifier = .array;
+ }
+ }
+
+ const name = init_d.d.name;
+ if (init_d.d.ty.is(.auto_type)) {
+ if (init_d.initializer.node == .none) {
+ init_d.d.ty = Type.invalid;
+ try p.errStr(.auto_type_requires_initializer, name, p.tokSlice(name));
+ return init_d;
+ } else {
+ init_d.d.ty.specifier = init_d.initializer.ty.specifier;
+ init_d.d.ty.data = init_d.initializer.ty.data;
+ }
+ }
+ if (apply_var_attributes) {
+ init_d.d.ty = try Attribute.applyVariableAttributes(p, init_d.d.ty, attr_buf_top, null);
+ }
+ if (decl_spec.storage_class != .typedef and init_d.d.ty.hasIncompleteSize()) incomplete: {
+ const specifier = init_d.d.ty.canonicalize(.standard).specifier;
+ if (decl_spec.storage_class == .@"extern") switch (specifier) {
+ .@"struct", .@"union", .@"enum" => break :incomplete,
+ .incomplete_array => {
+ init_d.d.ty.decayArray();
+ break :incomplete;
+ },
+ else => {},
+ };
+ // if there was an initializer expression it must have contained an error
+ if (init_d.initializer.node != .none) break :incomplete;
+
+ if (p.func.ty == null) {
+ if (specifier == .incomplete_array) {
+ // TODO properly check this after finishing parsing
+ try p.errStr(.tentative_array, name, try p.typeStr(init_d.d.ty));
+ break :incomplete;
+ } else if (init_d.d.ty.getRecord()) |record| {
+ _ = try p.tentative_defs.getOrPutValue(p.comp.gpa, record.name, init_d.d.name);
+ break :incomplete;
+ } else if (init_d.d.ty.get(.@"enum")) |en| {
+ _ = try p.tentative_defs.getOrPutValue(p.comp.gpa, en.data.@"enum".name, init_d.d.name);
+ break :incomplete;
+ }
+ }
+ try p.errStr(.variable_incomplete_ty, name, try p.typeStr(init_d.d.ty));
+ }
+ return init_d;
+}
+
+/// typeSpec
+/// : keyword_void
+/// | keyword_auto_type
+/// | keyword_char
+/// | keyword_short
+/// | keyword_int
+/// | keyword_long
+/// | keyword_float
+/// | keyword_double
+/// | keyword_signed
+/// | keyword_unsigned
+/// | keyword_bool
+/// | keyword_c23_bool
+/// | keyword_complex
+/// | atomicTypeSpec
+/// | recordSpec
+/// | enumSpec
+/// | typedef // IDENTIFIER
+/// | typeof
+/// | keyword_bit_int '(' integerConstExpr ')'
+/// atomicTypeSpec : keyword_atomic '(' typeName ')'
+/// alignSpec
+/// : keyword_alignas '(' typeName ')'
+/// | keyword_alignas '(' integerConstExpr ')'
+/// | keyword_c23_alignas '(' typeName ')'
+/// | keyword_c23_alignas '(' integerConstExpr ')'
+fn typeSpec(p: *Parser, ty: *Type.Builder) Error!bool {
+ const start = p.tok_i;
+ while (true) {
+ try p.attributeSpecifier();
+
+ if (try p.typeof()) |inner_ty| {
+ try ty.combineFromTypeof(p, inner_ty, start);
+ continue;
+ }
+ if (try p.typeQual(&ty.qual)) continue;
+ switch (p.tok_ids[p.tok_i]) {
+ .keyword_void => try ty.combine(p, .void, p.tok_i),
+ .keyword_auto_type => {
+ try p.errTok(.auto_type_extension, p.tok_i);
+ try ty.combine(p, .auto_type, p.tok_i);
+ },
+ .keyword_bool, .keyword_c23_bool => try ty.combine(p, .bool, p.tok_i),
+ .keyword_int8, .keyword_int8_2, .keyword_char => try ty.combine(p, .char, p.tok_i),
+ .keyword_int16, .keyword_int16_2, .keyword_short => try ty.combine(p, .short, p.tok_i),
+ .keyword_int32, .keyword_int32_2, .keyword_int => try ty.combine(p, .int, p.tok_i),
+ .keyword_long => try ty.combine(p, .long, p.tok_i),
+ .keyword_int64, .keyword_int64_2 => try ty.combine(p, .long_long, p.tok_i),
+ .keyword_int128 => try ty.combine(p, .int128, p.tok_i),
+ .keyword_signed => try ty.combine(p, .signed, p.tok_i),
+ .keyword_unsigned => try ty.combine(p, .unsigned, p.tok_i),
+ .keyword_fp16 => try ty.combine(p, .fp16, p.tok_i),
+ .keyword_float16 => try ty.combine(p, .float16, p.tok_i),
+ .keyword_float => try ty.combine(p, .float, p.tok_i),
+ .keyword_double => try ty.combine(p, .double, p.tok_i),
+ .keyword_complex => try ty.combine(p, .complex, p.tok_i),
+ .keyword_float80 => try ty.combine(p, .float80, p.tok_i),
+ .keyword_float128 => try ty.combine(p, .float128, p.tok_i),
+ .keyword_atomic => {
+ const atomic_tok = p.tok_i;
+ p.tok_i += 1;
+ const l_paren = p.eatToken(.l_paren) orelse {
+ // _Atomic qualifier not _Atomic(typeName)
+ p.tok_i = atomic_tok;
+ break;
+ };
+ const inner_ty = (try p.typeName()) orelse {
+ try p.err(.expected_type);
+ return error.ParsingFailed;
+ };
+ try p.expectClosing(l_paren, .r_paren);
+
+ const new_spec = Type.Builder.fromType(inner_ty);
+ try ty.combine(p, new_spec, atomic_tok);
+
+ if (ty.qual.atomic != null)
+ try p.errStr(.duplicate_decl_spec, atomic_tok, "atomic")
+ else
+ ty.qual.atomic = atomic_tok;
+ continue;
+ },
+ .keyword_alignas,
+ .keyword_c23_alignas,
+ => {
+ const align_tok = p.tok_i;
+ p.tok_i += 1;
+ const l_paren = try p.expectToken(.l_paren);
+ const typename_start = p.tok_i;
+ if (try p.typeName()) |inner_ty| {
+ if (!inner_ty.alignable()) {
+ try p.errStr(.invalid_alignof, typename_start, try p.typeStr(inner_ty));
+ }
+ const alignment = Attribute.Alignment{ .requested = inner_ty.alignof(p.comp) };
+ try p.attr_buf.append(p.gpa, .{
+ .attr = .{ .tag = .aligned, .args = .{
+ .aligned = .{ .alignment = alignment, .__name_tok = align_tok },
+ }, .syntax = .keyword },
+ .tok = align_tok,
+ });
+ } else {
+ const arg_start = p.tok_i;
+ const res = try p.integerConstExpr(.no_const_decl_folding);
+ if (!res.val.isZero()) {
+ var args = Attribute.initArguments(.aligned, align_tok);
+ if (p.diagnose(.aligned, &args, 0, res)) |msg| {
+ try p.errExtra(msg.tag, arg_start, msg.extra);
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ }
+ args.aligned.alignment.?.node = res.node;
+ try p.attr_buf.append(p.gpa, .{
+ .attr = .{ .tag = .aligned, .args = args, .syntax = .keyword },
+ .tok = align_tok,
+ });
+ }
+ }
+ try p.expectClosing(l_paren, .r_paren);
+ continue;
+ },
+ .keyword_stdcall,
+ .keyword_stdcall2,
+ .keyword_thiscall,
+ .keyword_thiscall2,
+ .keyword_vectorcall,
+ .keyword_vectorcall2,
+ => try p.attr_buf.append(p.gpa, .{
+ .attr = .{ .tag = .calling_convention, .args = .{
+ .calling_convention = .{ .cc = switch (p.tok_ids[p.tok_i]) {
+ .keyword_stdcall,
+ .keyword_stdcall2,
+ => .stdcall,
+ .keyword_thiscall,
+ .keyword_thiscall2,
+ => .thiscall,
+ .keyword_vectorcall,
+ .keyword_vectorcall2,
+ => .vectorcall,
+ else => unreachable,
+ } },
+ }, .syntax = .keyword },
+ .tok = p.tok_i,
+ }),
+ .keyword_struct, .keyword_union => {
+ const tag_tok = p.tok_i;
+ const record_ty = try p.recordSpec();
+ try ty.combine(p, Type.Builder.fromType(record_ty), tag_tok);
+ continue;
+ },
+ .keyword_enum => {
+ const tag_tok = p.tok_i;
+ const enum_ty = try p.enumSpec();
+ try ty.combine(p, Type.Builder.fromType(enum_ty), tag_tok);
+ continue;
+ },
+ .identifier, .extended_identifier => {
+ var interned_name = try p.comp.intern(p.tokSlice(p.tok_i));
+ var declspec_found = false;
+
+ if (interned_name == p.string_ids.declspec_id) {
+ try p.errTok(.declspec_not_enabled, p.tok_i);
+ p.tok_i += 1;
+ if (p.eatToken(.l_paren)) |_| {
+ p.skipTo(.r_paren);
+ continue;
+ }
+ declspec_found = true;
+ }
+ if (ty.typedef != null) break;
+ if (declspec_found) {
+ interned_name = try p.comp.intern(p.tokSlice(p.tok_i));
+ }
+ const typedef = (try p.syms.findTypedef(p, interned_name, p.tok_i, ty.specifier != .none)) orelse break;
+ if (!ty.combineTypedef(p, typedef.ty, typedef.tok)) break;
+ },
+ .keyword_bit_int => {
+ try p.err(.bit_int);
+ const bit_int_tok = p.tok_i;
+ p.tok_i += 1;
+ const l_paren = try p.expectToken(.l_paren);
+ const res = try p.integerConstExpr(.gnu_folding_extension);
+ try p.expectClosing(l_paren, .r_paren);
+
+ var bits: i16 = undefined;
+ if (res.val.tag == .unavailable) {
+ try p.errTok(.expected_integer_constant_expr, bit_int_tok);
+ return error.ParsingFailed;
+ } else if (res.val.compare(.lte, Value.int(0), res.ty, p.comp)) {
+ bits = -1;
+ } else if (res.val.compare(.gt, Value.int(128), res.ty, p.comp)) {
+ bits = 129;
+ } else {
+ bits = res.val.getInt(i16);
+ }
+
+ try ty.combine(p, .{ .bit_int = bits }, bit_int_tok);
+ continue;
+ },
+ else => break,
+ }
+ // consume single token specifiers here
+ p.tok_i += 1;
+ }
+ return p.tok_i != start;
+}
+
+fn getAnonymousName(p: *Parser, kind_tok: TokenIndex) !StringId {
+ const loc = p.pp.tokens.items(.loc)[kind_tok];
+ const source = p.comp.getSource(loc.id);
+ const line_col = source.lineCol(loc);
+
+ const kind_str = switch (p.tok_ids[kind_tok]) {
+ .keyword_struct, .keyword_union, .keyword_enum => p.tokSlice(kind_tok),
+ else => "record field",
+ };
+
+ const str = try std.fmt.allocPrint(
+ p.arena,
+ "(anonymous {s} at {s}:{d}:{d})",
+ .{ kind_str, source.path, line_col.line_no, line_col.col },
+ );
+ return p.comp.intern(str);
+}
+
+/// recordSpec
+/// : (keyword_struct | keyword_union) IDENTIFIER? { recordDecl* }
+/// | (keyword_struct | keyword_union) IDENTIFIER
+fn recordSpec(p: *Parser) Error!Type {
+ const starting_pragma_pack = p.pragma_pack;
+ const kind_tok = p.tok_i;
+ const is_struct = p.tok_ids[kind_tok] == .keyword_struct;
+ p.tok_i += 1;
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ try p.attributeSpecifier();
+
+ const maybe_ident = try p.eatIdentifier();
+ const l_brace = p.eatToken(.l_brace) orelse {
+ const ident = maybe_ident orelse {
+ try p.err(.ident_or_l_brace);
+ return error.ParsingFailed;
+ };
+ // check if this is a reference to a previous type
+ const interned_name = try p.comp.intern(p.tokSlice(ident));
+ if (try p.syms.findTag(p, interned_name, p.tok_ids[kind_tok], ident, p.tok_ids[p.tok_i])) |prev| {
+ return prev.ty;
+ } else {
+ // this is a forward declaration, create a new record Type.
+ const record_ty = try Type.Record.create(p.arena, interned_name);
+ const ty = try Attribute.applyTypeAttributes(p, .{
+ .specifier = if (is_struct) .@"struct" else .@"union",
+ .data = .{ .record = record_ty },
+ }, attr_buf_top, null);
+ try p.syms.syms.append(p.gpa, .{
+ .kind = if (is_struct) .@"struct" else .@"union",
+ .name = interned_name,
+ .tok = ident,
+ .ty = ty,
+ .val = .{},
+ });
+ try p.decl_buf.append(try p.addNode(.{
+ .tag = if (is_struct) .struct_forward_decl else .union_forward_decl,
+ .ty = ty,
+ .data = .{ .decl_ref = ident },
+ }));
+ return ty;
+ }
+ };
+
+ var done = false;
+ errdefer if (!done) p.skipTo(.r_brace);
+
+ // Get forward declared type or create a new one
+ var defined = false;
+ const record_ty: *Type.Record = if (maybe_ident) |ident| record_ty: {
+ const ident_str = p.tokSlice(ident);
+ const interned_name = try p.comp.intern(ident_str);
+ if (try p.syms.defineTag(p, interned_name, p.tok_ids[kind_tok], ident)) |prev| {
+ if (!prev.ty.hasIncompleteSize()) {
+ // if the record isn't incomplete, this is a redefinition
+ try p.errStr(.redefinition, ident, ident_str);
+ try p.errTok(.previous_definition, prev.tok);
+ } else {
+ defined = true;
+ break :record_ty prev.ty.get(if (is_struct) .@"struct" else .@"union").?.data.record;
+ }
+ }
+ break :record_ty try Type.Record.create(p.arena, interned_name);
+ } else try Type.Record.create(p.arena, try p.getAnonymousName(kind_tok));
+
+ // Initially create ty as a regular non-attributed type, since attributes for a record
+ // can be specified after the closing rbrace, which we haven't encountered yet.
+ var ty = Type{
+ .specifier = if (is_struct) .@"struct" else .@"union",
+ .data = .{ .record = record_ty },
+ };
+
+ // declare a symbol for the type
+ // We need to replace the symbol's type if it has attributes
+ var symbol_index: ?usize = null;
+ if (maybe_ident != null and !defined) {
+ symbol_index = p.syms.syms.len;
+ try p.syms.syms.append(p.gpa, .{
+ .kind = if (is_struct) .@"struct" else .@"union",
+ .name = record_ty.name,
+ .tok = maybe_ident.?,
+ .ty = ty,
+ .val = .{},
+ });
+ }
+
+ // reserve space for this record
+ try p.decl_buf.append(.none);
+ const decl_buf_top = p.decl_buf.items.len;
+ const record_buf_top = p.record_buf.items.len;
+ errdefer p.decl_buf.items.len = decl_buf_top - 1;
+ defer {
+ p.decl_buf.items.len = decl_buf_top;
+ p.record_buf.items.len = record_buf_top;
+ }
+
+ const old_record = p.record;
+ const old_members = p.record_members.items.len;
+ const old_field_attr_start = p.field_attr_buf.items.len;
+ p.record = .{
+ .kind = p.tok_ids[kind_tok],
+ .start = p.record_members.items.len,
+ .field_attr_start = p.field_attr_buf.items.len,
+ };
+ defer p.record = old_record;
+ defer p.record_members.items.len = old_members;
+ defer p.field_attr_buf.items.len = old_field_attr_start;
+
+ try p.recordDecls();
+
+ if (p.record.flexible_field) |some| {
+ if (p.record_buf.items[record_buf_top..].len == 1 and is_struct) {
+ try p.errTok(.flexible_in_empty, some);
+ }
+ }
+
+ for (p.record_buf.items[record_buf_top..]) |field| {
+ if (field.ty.hasIncompleteSize() and !field.ty.is(.incomplete_array)) break;
+ } else {
+ record_ty.fields = try p.arena.dupe(Type.Record.Field, p.record_buf.items[record_buf_top..]);
+ }
+ if (old_field_attr_start < p.field_attr_buf.items.len) {
+ const field_attr_slice = p.field_attr_buf.items[old_field_attr_start..];
+ const duped = try p.arena.dupe([]const Attribute, field_attr_slice);
+ record_ty.field_attributes = duped.ptr;
+ }
+
+ if (p.record_buf.items.len == record_buf_top) {
+ try p.errStr(.empty_record, kind_tok, p.tokSlice(kind_tok));
+ try p.errStr(.empty_record_size, kind_tok, p.tokSlice(kind_tok));
+ }
+ try p.expectClosing(l_brace, .r_brace);
+ done = true;
+ try p.attributeSpecifier();
+
+ ty = try Attribute.applyTypeAttributes(p, .{
+ .specifier = if (is_struct) .@"struct" else .@"union",
+ .data = .{ .record = record_ty },
+ }, attr_buf_top, null);
+ if (ty.specifier == .attributed and symbol_index != null) {
+ p.syms.syms.items(.ty)[symbol_index.?] = ty;
+ }
+
+ if (!ty.hasIncompleteSize()) {
+ const pragma_pack_value = switch (p.comp.langopts.emulate) {
+ .clang => starting_pragma_pack,
+ .gcc => p.pragma_pack,
+ // TODO: msvc considers `#pragma pack` on a per-field basis
+ .msvc => p.pragma_pack,
+ };
+ record_layout.compute(record_ty, ty, p.pp.comp, pragma_pack_value);
+ }
+
+ // finish by creating a node
+ var node: Tree.Node = .{
+ .tag = if (is_struct) .struct_decl_two else .union_decl_two,
+ .ty = ty,
+ .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+ };
+ const record_decls = p.decl_buf.items[decl_buf_top..];
+ switch (record_decls.len) {
+ 0 => {},
+ 1 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = .none } },
+ 2 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = record_decls[1] } },
+ else => {
+ node.tag = if (is_struct) .struct_decl else .union_decl;
+ node.data = .{ .range = try p.addList(record_decls) };
+ },
+ }
+ p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
+ if (p.func.ty == null) {
+ _ = p.tentative_defs.remove(record_ty.name);
+ }
+ return ty;
+}
+
+/// recordDecl
+/// : specQual (recordDeclarator (',' recordDeclarator)*)? ;
+/// | staticAssert
+fn recordDecls(p: *Parser) Error!void {
+ while (true) {
+ if (try p.pragma()) continue;
+ if (try p.parseOrNextDecl(staticAssert)) continue;
+ if (p.eatToken(.keyword_extension)) |_| {
+ const saved_extension = p.extension_suppressed;
+ defer p.extension_suppressed = saved_extension;
+ p.extension_suppressed = true;
+
+ if (try p.parseOrNextDecl(recordDeclarator)) continue;
+ try p.err(.expected_type);
+ p.nextExternDecl();
+ continue;
+ }
+ if (try p.parseOrNextDecl(recordDeclarator)) continue;
+ break;
+ }
+}
+
+/// recordDeclarator : keyword_extension? declarator (':' integerConstExpr)?
+fn recordDeclarator(p: *Parser) Error!bool {
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ const base_ty = (try p.specQual()) orelse return false;
+
+ try p.attributeSpecifier(); // .record
+ while (true) {
+ const this_decl_top = p.attr_buf.len;
+ defer p.attr_buf.len = this_decl_top;
+
+ try p.attributeSpecifier();
+
+ // 0 means unnamed
+ var name_tok: TokenIndex = 0;
+ var ty = base_ty;
+ if (ty.is(.auto_type)) {
+ try p.errStr(.auto_type_not_allowed, p.tok_i, if (p.record.kind == .keyword_struct) "struct member" else "union member");
+ ty = Type.invalid;
+ }
+ var bits_node: NodeIndex = .none;
+ var bits: ?u32 = null;
+ const first_tok = p.tok_i;
+ if (try p.declarator(ty, .record)) |d| {
+ name_tok = d.name;
+ ty = d.ty;
+ }
+
+ if (p.eatToken(.colon)) |_| bits: {
+ const bits_tok = p.tok_i;
+ const res = try p.integerConstExpr(.gnu_folding_extension);
+ if (!ty.isInt()) {
+ try p.errStr(.non_int_bitfield, first_tok, try p.typeStr(ty));
+ break :bits;
+ }
+
+ if (res.val.tag == .unavailable) {
+ try p.errTok(.expected_integer_constant_expr, bits_tok);
+ break :bits;
+ } else if (res.val.compare(.lt, Value.int(0), res.ty, p.comp)) {
+ try p.errExtra(.negative_bitwidth, first_tok, .{
+ .signed = res.val.signExtend(res.ty, p.comp),
+ });
+ break :bits;
+ }
+
+ // incomplete size error is reported later
+ const bit_size = ty.bitSizeof(p.comp) orelse break :bits;
+ if (res.val.compare(.gt, Value.int(bit_size), res.ty, p.comp)) {
+ try p.errTok(.bitfield_too_big, name_tok);
+ break :bits;
+ } else if (res.val.isZero() and name_tok != 0) {
+ try p.errTok(.zero_width_named_field, name_tok);
+ break :bits;
+ }
+
+ bits = res.val.getInt(u32);
+ bits_node = res.node;
+ }
+
+ try p.attributeSpecifier(); // .record
+ const to_append = try Attribute.applyFieldAttributes(p, &ty, attr_buf_top);
+
+ const any_fields_have_attrs = p.field_attr_buf.items.len > p.record.field_attr_start;
+
+ if (any_fields_have_attrs) {
+ try p.field_attr_buf.append(to_append);
+ } else {
+ if (to_append.len > 0) {
+ const preceding = p.record_members.items.len - p.record.start;
+ if (preceding > 0) {
+ try p.field_attr_buf.appendNTimes(&.{}, preceding);
+ }
+ try p.field_attr_buf.append(to_append);
+ }
+ }
+
+ if (name_tok == 0 and bits_node == .none) unnamed: {
+ if (ty.is(.@"enum") or ty.hasIncompleteSize()) break :unnamed;
+ if (ty.isAnonymousRecord(p.comp)) {
+ // An anonymous record appears as indirect fields on the parent
+ try p.record_buf.append(.{
+ .name = try p.getAnonymousName(first_tok),
+ .ty = ty,
+ });
+ const node = try p.addNode(.{
+ .tag = .indirect_record_field_decl,
+ .ty = ty,
+ .data = undefined,
+ });
+ try p.decl_buf.append(node);
+ try p.record.addFieldsFromAnonymous(p, ty);
+ break; // must be followed by a semicolon
+ }
+ try p.err(.missing_declaration);
+ } else {
+ const interned_name = if (name_tok != 0) try p.comp.intern(p.tokSlice(name_tok)) else try p.getAnonymousName(first_tok);
+ try p.record_buf.append(.{
+ .name = interned_name,
+ .ty = ty,
+ .name_tok = name_tok,
+ .bit_width = bits,
+ });
+ if (name_tok != 0) try p.record.addField(p, interned_name, name_tok);
+ const node = try p.addNode(.{
+ .tag = .record_field_decl,
+ .ty = ty,
+ .data = .{ .decl = .{ .name = name_tok, .node = bits_node } },
+ });
+ try p.decl_buf.append(node);
+ }
+
+ if (ty.isFunc()) {
+ try p.errTok(.func_field, first_tok);
+ } else if (ty.is(.variable_len_array)) {
+ try p.errTok(.vla_field, first_tok);
+ } else if (ty.is(.incomplete_array)) {
+ if (p.record.kind == .keyword_union) {
+ try p.errTok(.flexible_in_union, first_tok);
+ }
+ if (p.record.flexible_field) |some| {
+ if (p.record.kind == .keyword_struct) {
+ try p.errTok(.flexible_non_final, some);
+ }
+ }
+ p.record.flexible_field = first_tok;
+ } else if (ty.specifier != .invalid and ty.hasIncompleteSize()) {
+ try p.errStr(.field_incomplete_ty, first_tok, try p.typeStr(ty));
+ } else if (p.record.flexible_field) |some| {
+ if (some != first_tok and p.record.kind == .keyword_struct) try p.errTok(.flexible_non_final, some);
+ }
+ if (p.eatToken(.comma) == null) break;
+ }
+
+ if (p.eatToken(.semicolon) == null) {
+ const tok_id = p.tok_ids[p.tok_i];
+ if (tok_id == .r_brace) {
+ try p.err(.missing_semicolon);
+ } else {
+ return p.errExpectedToken(.semicolon, tok_id);
+ }
+ }
+
+ return true;
+}
+
+/// specQual : (typeSpec | typeQual | alignSpec)+
+fn specQual(p: *Parser) Error!?Type {
+ var spec: Type.Builder = .{};
+ if (try p.typeSpec(&spec)) {
+ return try spec.finish(p);
+ }
+ return null;
+}
+
+/// enumSpec
+/// : keyword_enum IDENTIFIER? (: typeName)? { enumerator (',' enumerator)? ',') }
+/// | keyword_enum IDENTIFIER (: typeName)?
+fn enumSpec(p: *Parser) Error!Type {
+ const enum_tok = p.tok_i;
+ p.tok_i += 1;
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ try p.attributeSpecifier();
+
+ const maybe_ident = try p.eatIdentifier();
+ const fixed_ty = if (p.eatToken(.colon)) |colon| fixed: {
+ const fixed = (try p.typeName()) orelse {
+ if (p.record.kind != .invalid) {
+ // This is a bit field.
+ p.tok_i -= 1;
+ break :fixed null;
+ }
+ try p.err(.expected_type);
+ try p.errTok(.enum_fixed, colon);
+ break :fixed null;
+ };
+ try p.errTok(.enum_fixed, colon);
+ break :fixed fixed;
+ } else null;
+
+ const l_brace = p.eatToken(.l_brace) orelse {
+ const ident = maybe_ident orelse {
+ try p.err(.ident_or_l_brace);
+ return error.ParsingFailed;
+ };
+ // check if this is a reference to a previous type
+ const interned_name = try p.comp.intern(p.tokSlice(ident));
+ if (try p.syms.findTag(p, interned_name, .keyword_enum, ident, p.tok_ids[p.tok_i])) |prev| {
+ try p.checkEnumFixedTy(fixed_ty, ident, prev);
+ return prev.ty;
+ } else {
+ // this is a forward declaration, create a new enum Type.
+ const enum_ty = try Type.Enum.create(p.arena, interned_name, fixed_ty);
+ const ty = try Attribute.applyTypeAttributes(p, .{
+ .specifier = .@"enum",
+ .data = .{ .@"enum" = enum_ty },
+ }, attr_buf_top, null);
+ try p.syms.syms.append(p.gpa, .{
+ .kind = .@"enum",
+ .name = interned_name,
+ .tok = ident,
+ .ty = ty,
+ .val = .{},
+ });
+ try p.decl_buf.append(try p.addNode(.{
+ .tag = .enum_forward_decl,
+ .ty = ty,
+ .data = .{ .decl_ref = ident },
+ }));
+ return ty;
+ }
+ };
+
+ var done = false;
+ errdefer if (!done) p.skipTo(.r_brace);
+
+ // Get forward declared type or create a new one
+ var defined = false;
+ const enum_ty: *Type.Enum = if (maybe_ident) |ident| enum_ty: {
+ const ident_str = p.tokSlice(ident);
+ const interned_name = try p.comp.intern(ident_str);
+ if (try p.syms.defineTag(p, interned_name, .keyword_enum, ident)) |prev| {
+ const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
+ if (!enum_ty.isIncomplete() and !enum_ty.fixed) {
+ // if the enum isn't incomplete, this is a redefinition
+ try p.errStr(.redefinition, ident, ident_str);
+ try p.errTok(.previous_definition, prev.tok);
+ } else {
+ try p.checkEnumFixedTy(fixed_ty, ident, prev);
+ defined = true;
+ break :enum_ty enum_ty;
+ }
+ }
+ break :enum_ty try Type.Enum.create(p.arena, interned_name, fixed_ty);
+ } else try Type.Enum.create(p.arena, try p.getAnonymousName(enum_tok), fixed_ty);
+
+ // reserve space for this enum
+ try p.decl_buf.append(.none);
+ const decl_buf_top = p.decl_buf.items.len;
+ const list_buf_top = p.list_buf.items.len;
+ const enum_buf_top = p.enum_buf.items.len;
+ errdefer p.decl_buf.items.len = decl_buf_top - 1;
+ defer {
+ p.decl_buf.items.len = decl_buf_top;
+ p.list_buf.items.len = list_buf_top;
+ p.enum_buf.items.len = enum_buf_top;
+ }
+
+ const sym_stack_top = p.syms.syms.len;
+ var e = Enumerator.init(fixed_ty);
+ while (try p.enumerator(&e)) |field_and_node| {
+ try p.enum_buf.append(field_and_node.field);
+ try p.list_buf.append(field_and_node.node);
+ if (p.eatToken(.comma) == null) break;
+ }
+
+ if (p.enum_buf.items.len == enum_buf_top) try p.err(.empty_enum);
+ try p.expectClosing(l_brace, .r_brace);
+ done = true;
+ try p.attributeSpecifier();
+
+ const ty = try Attribute.applyTypeAttributes(p, .{
+ .specifier = .@"enum",
+ .data = .{ .@"enum" = enum_ty },
+ }, attr_buf_top, null);
+ if (!enum_ty.fixed) {
+ const tag_specifier = try e.getTypeSpecifier(p, ty.enumIsPacked(p.comp), maybe_ident orelse enum_tok);
+ enum_ty.tag_ty = .{ .specifier = tag_specifier };
+ }
+
+ const enum_fields = p.enum_buf.items[enum_buf_top..];
+ const field_nodes = p.list_buf.items[list_buf_top..];
+
+ if (fixed_ty == null) {
+ const vals = p.syms.syms.items(.val)[sym_stack_top..];
+ const types = p.syms.syms.items(.ty)[sym_stack_top..];
+
+ for (enum_fields, 0..) |*field, i| {
+ if (field.ty.eql(Type.int, p.comp, false)) continue;
+
+ var res = Result{ .node = field.node, .ty = field.ty, .val = vals[i] };
+ const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some|
+ Type{ .specifier = some }
+ else if (res.intFitsInType(p, Type.int))
+ Type.int
+ else if (!res.ty.eql(enum_ty.tag_ty, p.comp, false))
+ enum_ty.tag_ty
+ else
+ continue;
+
+ vals[i].intCast(field.ty, dest_ty, p.comp);
+ types[i] = dest_ty;
+ p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty;
+ field.ty = dest_ty;
+ res.ty = dest_ty;
+
+ if (res.node != .none) {
+ try res.implicitCast(p, .int_cast);
+ field.node = res.node;
+ p.nodes.items(.data)[@intFromEnum(field_nodes[i])].decl.node = res.node;
+ }
+ }
+ }
+
+ enum_ty.fields = try p.arena.dupe(Type.Enum.Field, enum_fields);
+
+ // declare a symbol for the type
+ if (maybe_ident != null and !defined) {
+ try p.syms.syms.append(p.gpa, .{
+ .kind = .@"enum",
+ .name = enum_ty.name,
+ .ty = ty,
+ .tok = maybe_ident.?,
+ .val = .{},
+ });
+ }
+
+ // finish by creating a node
+ var node: Tree.Node = .{ .tag = .enum_decl_two, .ty = ty, .data = .{
+ .bin = .{ .lhs = .none, .rhs = .none },
+ } };
+ switch (field_nodes.len) {
+ 0 => {},
+ 1 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = .none } },
+ 2 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = field_nodes[1] } },
+ else => {
+ node.tag = .enum_decl;
+ node.data = .{ .range = try p.addList(field_nodes) };
+ },
+ }
+ p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
+ if (p.func.ty == null) {
+ _ = p.tentative_defs.remove(enum_ty.name);
+ }
+ return ty;
+}
+
+fn checkEnumFixedTy(p: *Parser, fixed_ty: ?Type, ident_tok: TokenIndex, prev: Symbol) !void {
+ const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
+ if (fixed_ty) |some| {
+ if (!enum_ty.fixed) {
+ try p.errTok(.enum_prev_nonfixed, ident_tok);
+ try p.errTok(.previous_definition, prev.tok);
+ return error.ParsingFailed;
+ }
+
+ if (!enum_ty.tag_ty.eql(some, p.comp, false)) {
+ const str = try p.typePairStrExtra(some, " (was ", enum_ty.tag_ty);
+ try p.errStr(.enum_different_explicit_ty, ident_tok, str);
+ try p.errTok(.previous_definition, prev.tok);
+ return error.ParsingFailed;
+ }
+ } else if (enum_ty.fixed) {
+ try p.errTok(.enum_prev_fixed, ident_tok);
+ try p.errTok(.previous_definition, prev.tok);
+ return error.ParsingFailed;
+ }
+}
+
+const Enumerator = struct {
+ res: Result,
+ num_positive_bits: usize = 0,
+ num_negative_bits: usize = 0,
+ fixed: bool,
+
+ fn init(fixed_ty: ?Type) Enumerator {
+ return .{
+ .res = .{
+ .ty = fixed_ty orelse .{ .specifier = .int },
+ .val = .{ .tag = .unavailable },
+ },
+ .fixed = fixed_ty != null,
+ };
+ }
+
+ /// Increment enumerator value adjusting type if needed.
+ fn incr(e: *Enumerator, p: *Parser, tok: TokenIndex) !void {
+ e.res.node = .none;
+ const old_val = e.res.val;
+ if (old_val.tag == .unavailable) {
+ // First enumerator, set to 0 fits in all types.
+ e.res.val = Value.int(0);
+ return;
+ }
+ if (e.res.val.add(e.res.val, Value.int(1), e.res.ty, p.comp)) {
+ const byte_size = e.res.ty.sizeof(p.comp).?;
+ const bit_size: u8 = @intCast(if (e.res.ty.isUnsignedInt(p.comp)) byte_size * 8 else byte_size * 8 - 1);
+ if (e.fixed) {
+ try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
+ return;
+ }
+ const new_ty = if (p.comp.nextLargestIntSameSign(e.res.ty)) |larger| blk: {
+ try p.errTok(.enumerator_overflow, tok);
+ break :blk larger;
+ } else blk: {
+ try p.errExtra(.enum_not_representable, tok, .{ .pow_2_as_string = bit_size });
+ break :blk Type{ .specifier = .ulong_long };
+ };
+ e.res.ty = new_ty;
+ _ = e.res.val.add(old_val, Value.int(1), e.res.ty, p.comp);
+ }
+ }
+
+ /// Set enumerator value to specified value.
+ fn set(e: *Enumerator, p: *Parser, res: Result, tok: TokenIndex) !void {
+ if (res.ty.specifier == .invalid) return;
+ if (e.fixed and !res.ty.eql(e.res.ty, p.comp, false)) {
+ if (!res.intFitsInType(p, e.res.ty)) {
+ try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
+ return error.ParsingFailed;
+ }
+ var copy = res;
+ copy.ty = e.res.ty;
+ try copy.implicitCast(p, .int_cast);
+ e.res = copy;
+ } else {
+ e.res = res;
+ try e.res.intCast(p, e.res.ty.integerPromotion(p.comp), tok);
+ }
+ }
+
+ fn getTypeSpecifier(e: *const Enumerator, p: *Parser, is_packed: bool, tok: TokenIndex) !Type.Specifier {
+ if (p.comp.fixedEnumTagSpecifier()) |tag_specifier| return tag_specifier;
+
+ const char_width = (Type{ .specifier = .schar }).sizeof(p.comp).? * 8;
+ const short_width = (Type{ .specifier = .short }).sizeof(p.comp).? * 8;
+ const int_width = (Type{ .specifier = .int }).sizeof(p.comp).? * 8;
+ if (e.num_negative_bits > 0) {
+ if (is_packed and e.num_negative_bits <= char_width and e.num_positive_bits < char_width) {
+ return .schar;
+ } else if (is_packed and e.num_negative_bits <= short_width and e.num_positive_bits < short_width) {
+ return .short;
+ } else if (e.num_negative_bits <= int_width and e.num_positive_bits < int_width) {
+ return .int;
+ }
+ const long_width = (Type{ .specifier = .long }).sizeof(p.comp).? * 8;
+ if (e.num_negative_bits <= long_width and e.num_positive_bits < long_width) {
+ return .long;
+ }
+ const long_long_width = (Type{ .specifier = .long_long }).sizeof(p.comp).? * 8;
+ if (e.num_negative_bits > long_long_width or e.num_positive_bits >= long_long_width) {
+ try p.errTok(.enum_too_large, tok);
+ }
+ return .long_long;
+ }
+ if (is_packed and e.num_positive_bits <= char_width) {
+ return .uchar;
+ } else if (is_packed and e.num_positive_bits <= short_width) {
+ return .ushort;
+ } else if (e.num_positive_bits <= int_width) {
+ return .uint;
+ } else if (e.num_positive_bits <= (Type{ .specifier = .long }).sizeof(p.comp).? * 8) {
+ return .ulong;
+ }
+ return .ulong_long;
+ }
+};
+
+const EnumFieldAndNode = struct { field: Type.Enum.Field, node: NodeIndex };
+
+/// enumerator : IDENTIFIER ('=' integerConstExpr)
+fn enumerator(p: *Parser, e: *Enumerator) Error!?EnumFieldAndNode {
+ _ = try p.pragma();
+ const name_tok = (try p.eatIdentifier()) orelse {
+ if (p.tok_ids[p.tok_i] == .r_brace) return null;
+ try p.err(.expected_identifier);
+ p.skipTo(.r_brace);
+ return error.ParsingFailed;
+ };
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ try p.attributeSpecifier();
+
+ const err_start = p.comp.diag.list.items.len;
+ if (p.eatToken(.equal)) |_| {
+ const specified = try p.integerConstExpr(.gnu_folding_extension);
+ if (specified.val.tag == .unavailable) {
+ try p.errTok(.enum_val_unavailable, name_tok + 2);
+ try e.incr(p, name_tok);
+ } else {
+ try e.set(p, specified, name_tok);
+ }
+ } else {
+ try e.incr(p, name_tok);
+ }
+
+ var res = e.res;
+ res.ty = try Attribute.applyEnumeratorAttributes(p, res.ty, attr_buf_top);
+
+ if (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, Value.int(0), res.ty, p.comp)) {
+ e.num_positive_bits = @max(e.num_positive_bits, res.val.minUnsignedBits(res.ty, p.comp));
+ } else {
+ e.num_negative_bits = @max(e.num_negative_bits, res.val.minSignedBits(res.ty, p.comp));
+ }
+
+ if (err_start == p.comp.diag.list.items.len) {
+ // only do these warnings if we didn't already warn about overflow or non-representable values
+ if (e.res.val.compare(.lt, Value.int(0), e.res.ty, p.comp)) {
+ const val = e.res.val.getInt(i64);
+ if (val < (Type{ .specifier = .int }).minInt(p.comp)) {
+ try p.errExtra(.enumerator_too_small, name_tok, .{
+ .signed = val,
+ });
+ }
+ } else {
+ const val = e.res.val.getInt(u64);
+ if (val > (Type{ .specifier = .int }).maxInt(p.comp)) {
+ try p.errExtra(.enumerator_too_large, name_tok, .{
+ .unsigned = val,
+ });
+ }
+ }
+ }
+
+ const interned_name = try p.comp.intern(p.tokSlice(name_tok));
+ try p.syms.defineEnumeration(p, interned_name, res.ty, name_tok, e.res.val);
+ const node = try p.addNode(.{
+ .tag = .enum_field_decl,
+ .ty = res.ty,
+ .data = .{ .decl = .{
+ .name = name_tok,
+ .node = res.node,
+ } },
+ });
+ return EnumFieldAndNode{ .field = .{
+ .name = interned_name,
+ .ty = res.ty,
+ .name_tok = name_tok,
+ .node = res.node,
+ }, .node = node };
+}
+
+/// typeQual : keyword_const | keyword_restrict | keyword_volatile | keyword_atomic
+fn typeQual(p: *Parser, b: *Type.Qualifiers.Builder) Error!bool {
+ var any = false;
+ while (true) {
+ switch (p.tok_ids[p.tok_i]) {
+ .keyword_restrict, .keyword_restrict1, .keyword_restrict2 => {
+ if (b.restrict != null)
+ try p.errStr(.duplicate_decl_spec, p.tok_i, "restrict")
+ else
+ b.restrict = p.tok_i;
+ },
+ .keyword_const, .keyword_const1, .keyword_const2 => {
+ if (b.@"const" != null)
+ try p.errStr(.duplicate_decl_spec, p.tok_i, "const")
+ else
+ b.@"const" = p.tok_i;
+ },
+ .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
+ if (b.@"volatile" != null)
+ try p.errStr(.duplicate_decl_spec, p.tok_i, "volatile")
+ else
+ b.@"volatile" = p.tok_i;
+ },
+ .keyword_atomic => {
+ // _Atomic(typeName) instead of just _Atomic
+ if (p.tok_ids[p.tok_i + 1] == .l_paren) break;
+ if (b.atomic != null)
+ try p.errStr(.duplicate_decl_spec, p.tok_i, "atomic")
+ else
+ b.atomic = p.tok_i;
+ },
+ else => break,
+ }
+ p.tok_i += 1;
+ any = true;
+ }
+ return any;
+}
+
+const Declarator = struct {
+ name: TokenIndex,
+ ty: Type,
+ func_declarator: ?TokenIndex = null,
+ old_style_func: ?TokenIndex = null,
+};
+const DeclaratorKind = enum { normal, abstract, param, record };
+
+/// declarator : pointer? (IDENTIFIER | '(' declarator ')') directDeclarator*
+/// abstractDeclarator
+/// : pointer? ('(' abstractDeclarator ')')? directAbstractDeclarator*
+fn declarator(
+ p: *Parser,
+ base_type: Type,
+ kind: DeclaratorKind,
+) Error!?Declarator {
+ const start = p.tok_i;
+ var d = Declarator{ .name = 0, .ty = try p.pointer(base_type) };
+ if (base_type.is(.auto_type) and !d.ty.is(.auto_type)) {
+ try p.errTok(.auto_type_requires_plain_declarator, start);
+ return error.ParsingFailed;
+ }
+
+ const maybe_ident = p.tok_i;
+ if (kind != .abstract and (try p.eatIdentifier()) != null) {
+ d.name = maybe_ident;
+ const combine_tok = p.tok_i;
+ d.ty = try p.directDeclarator(d.ty, &d, kind);
+ try d.ty.validateCombinedType(p, combine_tok);
+ return d;
+ } else if (p.eatToken(.l_paren)) |l_paren| blk: {
+ var res = (try p.declarator(.{ .specifier = .void }, kind)) orelse {
+ p.tok_i = l_paren;
+ break :blk;
+ };
+ try p.expectClosing(l_paren, .r_paren);
+ const suffix_start = p.tok_i;
+ const outer = try p.directDeclarator(d.ty, &d, kind);
+ try res.ty.combine(outer);
+ try res.ty.validateCombinedType(p, suffix_start);
+ res.old_style_func = d.old_style_func;
+ return res;
+ }
+
+ const expected_ident = p.tok_i;
+
+ d.ty = try p.directDeclarator(d.ty, &d, kind);
+
+ if (kind == .normal and !d.ty.isEnumOrRecord()) {
+ try p.errTok(.expected_ident_or_l_paren, expected_ident);
+ return error.ParsingFailed;
+ }
+ try d.ty.validateCombinedType(p, expected_ident);
+ if (start == p.tok_i) return null;
+ return d;
+}
+
+/// directDeclarator
+/// : '[' typeQual* assignExpr? ']' directDeclarator?
+/// | '[' keyword_static typeQual* assignExpr ']' directDeclarator?
+/// | '[' typeQual+ keyword_static assignExpr ']' directDeclarator?
+/// | '[' typeQual* '*' ']' directDeclarator?
+/// | '(' paramDecls ')' directDeclarator?
+/// | '(' (IDENTIFIER (',' IDENTIFIER))? ')' directDeclarator?
+/// directAbstractDeclarator
+/// : '[' typeQual* assignExpr? ']'
+/// | '[' keyword_static typeQual* assignExpr ']'
+/// | '[' typeQual+ keyword_static assignExpr ']'
+/// | '[' '*' ']'
+/// | '(' paramDecls? ')'
+fn directDeclarator(p: *Parser, base_type: Type, d: *Declarator, kind: DeclaratorKind) Error!Type {
+ if (p.eatToken(.l_bracket)) |l_bracket| {
+ if (p.tok_ids[p.tok_i] == .l_bracket) {
+ switch (kind) {
+ .normal, .record => if (p.comp.langopts.standard.atLeast(.c2x)) {
+ p.tok_i -= 1;
+ return base_type;
+ },
+ .param, .abstract => {},
+ }
+ try p.err(.expected_expr);
+ return error.ParsingFailed;
+ }
+ var res_ty = Type{
+ // so that we can get any restrict type that might be present
+ .specifier = .pointer,
+ };
+ var quals = Type.Qualifiers.Builder{};
+
+ var got_quals = try p.typeQual(&quals);
+ var static = p.eatToken(.keyword_static);
+ if (static != null and !got_quals) got_quals = try p.typeQual(&quals);
+ var star = p.eatToken(.asterisk);
+ const size_tok = p.tok_i;
+
+ const const_decl_folding = p.const_decl_folding;
+ p.const_decl_folding = .gnu_vla_folding_extension;
+ const size = if (star) |_| Result{} else try p.assignExpr();
+ p.const_decl_folding = const_decl_folding;
+
+ try p.expectClosing(l_bracket, .r_bracket);
+
+ if (star != null and static != null) {
+ try p.errTok(.invalid_static_star, static.?);
+ static = null;
+ }
+ if (kind != .param) {
+ if (static != null)
+ try p.errTok(.static_non_param, l_bracket)
+ else if (got_quals)
+ try p.errTok(.array_qualifiers, l_bracket);
+ if (star) |some| try p.errTok(.star_non_param, some);
+ static = null;
+ quals = .{};
+ star = null;
+ } else {
+ try quals.finish(p, &res_ty);
+ }
+ if (static) |_| try size.expect(p);
+
+ if (base_type.is(.auto_type)) {
+ try p.errStr(.array_of_auto_type, d.name, p.tokSlice(d.name));
+ return error.ParsingFailed;
+ }
+ const outer = try p.directDeclarator(base_type, d, kind);
+ var max_bits = p.comp.target.ptrBitWidth();
+ if (max_bits > 61) max_bits = 61;
+ const max_bytes = (@as(u64, 1) << @truncate(max_bits)) - 1;
+ // `outer` is validated later so it may be invalid here
+ const outer_size = outer.sizeof(p.comp);
+ const max_elems = max_bytes / @max(1, outer_size orelse 1);
+
+ if (!size.ty.isInt()) {
+ try p.errStr(.array_size_non_int, size_tok, try p.typeStr(size.ty));
+ return error.ParsingFailed;
+ }
+ if (size.val.tag == .unavailable) {
+ if (size.node != .none) {
+ try p.errTok(.vla, size_tok);
+ if (p.func.ty == null and kind != .param and p.record.kind == .invalid) {
+ try p.errTok(.variable_len_array_file_scope, d.name);
+ }
+ const expr_ty = try p.arena.create(Type.Expr);
+ expr_ty.ty = .{ .specifier = .void };
+ expr_ty.node = size.node;
+ res_ty.data = .{ .expr = expr_ty };
+ res_ty.specifier = .variable_len_array;
+
+ if (static) |some| try p.errTok(.useless_static, some);
+ } else if (star) |_| {
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = .{ .specifier = .void };
+ res_ty.data = .{ .sub_type = elem_ty };
+ res_ty.specifier = .unspecified_variable_len_array;
+ } else {
+ const arr_ty = try p.arena.create(Type.Array);
+ arr_ty.elem = .{ .specifier = .void };
+ arr_ty.len = 0;
+ res_ty.data = .{ .array = arr_ty };
+ res_ty.specifier = .incomplete_array;
+ }
+ } else {
+ var size_val = size.val;
+ const size_t = p.comp.types.size;
+ if (size_val.isZero()) {
+ try p.errTok(.zero_length_array, l_bracket);
+ } else if (size_val.compare(.lt, Value.int(0), size_t, p.comp)) {
+ try p.errTok(.negative_array_size, l_bracket);
+ return error.ParsingFailed;
+ }
+ const arr_ty = try p.arena.create(Type.Array);
+ arr_ty.elem = .{ .specifier = .void };
+ if (size_val.compare(.gt, Value.int(max_elems), size_t, p.comp)) {
+ try p.errTok(.array_too_large, l_bracket);
+ arr_ty.len = max_elems;
+ } else {
+ arr_ty.len = size_val.getInt(u64);
+ }
+ res_ty.data = .{ .array = arr_ty };
+ res_ty.specifier = .array;
+ }
+
+ try res_ty.combine(outer);
+ return res_ty;
+ } else if (p.eatToken(.l_paren)) |l_paren| {
+ d.func_declarator = l_paren;
+
+ const func_ty = try p.arena.create(Type.Func);
+ func_ty.params = &.{};
+ func_ty.return_type.specifier = .void;
+ var specifier: Type.Specifier = .func;
+
+ if (p.eatToken(.ellipsis)) |_| {
+ try p.err(.param_before_var_args);
+ try p.expectClosing(l_paren, .r_paren);
+ var res_ty = Type{ .specifier = .func, .data = .{ .func = func_ty } };
+
+ const outer = try p.directDeclarator(base_type, d, kind);
+ try res_ty.combine(outer);
+ return res_ty;
+ }
+
+ if (try p.paramDecls()) |params| {
+ func_ty.params = params;
+ if (p.eatToken(.ellipsis)) |_| specifier = .var_args_func;
+ } else if (p.tok_ids[p.tok_i] == .r_paren) {
+ specifier = .var_args_func;
+ } else if (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) {
+ d.old_style_func = p.tok_i;
+ const param_buf_top = p.param_buf.items.len;
+ try p.syms.pushScope(p);
+ defer {
+ p.param_buf.items.len = param_buf_top;
+ p.syms.popScope();
+ }
+
+ specifier = .old_style_func;
+ while (true) {
+ const name_tok = try p.expectIdentifier();
+ const interned_name = try p.comp.intern(p.tokSlice(name_tok));
+ try p.syms.defineParam(p, interned_name, undefined, name_tok);
+ try p.param_buf.append(.{
+ .name = interned_name,
+ .name_tok = name_tok,
+ .ty = .{ .specifier = .int },
+ });
+ if (p.eatToken(.comma) == null) break;
+ }
+ func_ty.params = try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
+ } else {
+ try p.err(.expected_param_decl);
+ }
+
+ try p.expectClosing(l_paren, .r_paren);
+ var res_ty = Type{
+ .specifier = specifier,
+ .data = .{ .func = func_ty },
+ };
+
+ const outer = try p.directDeclarator(base_type, d, kind);
+ try res_ty.combine(outer);
+ return res_ty;
+ } else return base_type;
+}
+
+/// pointer : '*' typeQual* pointer?
+fn pointer(p: *Parser, base_ty: Type) Error!Type {
+ var ty = base_ty;
+ while (p.eatToken(.asterisk)) |_| {
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = ty;
+ ty = Type{
+ .specifier = .pointer,
+ .data = .{ .sub_type = elem_ty },
+ };
+ var quals = Type.Qualifiers.Builder{};
+ _ = try p.typeQual(&quals);
+ try quals.finish(p, &ty);
+ }
+ return ty;
+}
+
+/// paramDecls : paramDecl (',' paramDecl)* (',' '...')
+/// paramDecl : declSpec (declarator | abstractDeclarator)
+fn paramDecls(p: *Parser) Error!?[]Type.Func.Param {
+ // TODO warn about visibility of types declared here
+ const param_buf_top = p.param_buf.items.len;
+ defer p.param_buf.items.len = param_buf_top;
+ try p.syms.pushScope(p);
+ defer p.syms.popScope();
+
+ while (true) {
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ const param_decl_spec = if (try p.declSpec()) |some|
+ some
+ else if (p.param_buf.items.len == param_buf_top)
+ return null
+ else blk: {
+ var spec: Type.Builder = .{};
+ break :blk DeclSpec{ .ty = try spec.finish(p) };
+ };
+
+ var name_tok: TokenIndex = 0;
+ const first_tok = p.tok_i;
+ var param_ty = param_decl_spec.ty;
+ if (try p.declarator(param_decl_spec.ty, .param)) |some| {
+ if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
+ try p.attributeSpecifier();
+
+ name_tok = some.name;
+ param_ty = some.ty;
+ if (some.name != 0) {
+ const interned_name = try p.comp.intern(p.tokSlice(name_tok));
+ try p.syms.defineParam(p, interned_name, param_ty, name_tok);
+ }
+ }
+ param_ty = try Attribute.applyParameterAttributes(p, param_ty, attr_buf_top, .alignas_on_param);
+
+ if (param_ty.isFunc()) {
+ // params declared as functions are converted to function pointers
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = param_ty;
+ param_ty = Type{
+ .specifier = .pointer,
+ .data = .{ .sub_type = elem_ty },
+ };
+ } else if (param_ty.isArray()) {
+ // params declared as arrays are converted to pointers
+ param_ty.decayArray();
+ } else if (param_ty.is(.void)) {
+ // validate void parameters
+ if (p.param_buf.items.len == param_buf_top) {
+ if (p.tok_ids[p.tok_i] != .r_paren) {
+ try p.err(.void_only_param);
+ if (param_ty.anyQual()) try p.err(.void_param_qualified);
+ return error.ParsingFailed;
+ }
+ return &[0]Type.Func.Param{};
+ }
+ try p.err(.void_must_be_first_param);
+ return error.ParsingFailed;
+ }
+
+ try param_decl_spec.validateParam(p, ¶m_ty);
+ try p.param_buf.append(.{
+ .name = if (name_tok == 0) .empty else try p.comp.intern(p.tokSlice(name_tok)),
+ .name_tok = if (name_tok == 0) first_tok else name_tok,
+ .ty = param_ty,
+ });
+
+ if (p.eatToken(.comma) == null) break;
+ if (p.tok_ids[p.tok_i] == .ellipsis) break;
+ }
+ return try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
+}
+
+/// typeName : specQual abstractDeclarator
+fn typeName(p: *Parser) Error!?Type {
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ var ty = (try p.specQual()) orelse return null;
+ if (try p.declarator(ty, .abstract)) |some| {
+ if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
+ return try Attribute.applyTypeAttributes(p, some.ty, attr_buf_top, .align_ignored);
+ }
+ return try Attribute.applyTypeAttributes(p, ty, attr_buf_top, .align_ignored);
+}
+
+/// initializer
+/// : assignExpr
+/// | '{' initializerItems '}'
+fn initializer(p: *Parser, init_ty: Type) Error!Result {
+ // fast path for non-braced initializers
+ if (p.tok_ids[p.tok_i] != .l_brace) {
+ const tok = p.tok_i;
+ var res = try p.assignExpr();
+ try res.expect(p);
+ if (try p.coerceArrayInit(&res, tok, init_ty)) return res;
+ try p.coerceInit(&res, tok, init_ty);
+ return res;
+ }
+ if (init_ty.is(.auto_type)) {
+ try p.err(.auto_type_with_init_list);
+ return error.ParsingFailed;
+ }
+
+ var il: InitList = .{};
+ defer il.deinit(p.gpa);
+
+ _ = try p.initializerItem(&il, init_ty);
+
+ const res = try p.convertInitList(il, init_ty);
+ var res_ty = p.nodes.items(.ty)[@intFromEnum(res)];
+ res_ty.qual = init_ty.qual;
+ return Result{ .ty = res_ty, .node = res };
+}
+
+/// initializerItems : designation? initializer (',' designation? initializer)* ','?
+/// designation : designator+ '='
+/// designator
+/// : '[' integerConstExpr ']'
+/// | '.' identifier
+fn initializerItem(p: *Parser, il: *InitList, init_ty: Type) Error!bool {
+ const l_brace = p.eatToken(.l_brace) orelse {
+ const tok = p.tok_i;
+ var res = try p.assignExpr();
+ if (res.empty(p)) return false;
+
+ const arr = try p.coerceArrayInit(&res, tok, init_ty);
+ if (!arr) try p.coerceInit(&res, tok, init_ty);
+ if (il.tok != 0) {
+ try p.errTok(.initializer_overrides, tok);
+ try p.errTok(.previous_initializer, il.tok);
+ }
+ il.node = res.node;
+ il.tok = tok;
+ return true;
+ };
+
+ const is_scalar = init_ty.isScalar();
+ const is_complex = init_ty.isComplex();
+ const scalar_inits_needed: usize = if (is_complex) 2 else 1;
+ if (p.eatToken(.r_brace)) |_| {
+ if (is_scalar) try p.errTok(.empty_scalar_init, l_brace);
+ if (il.tok != 0) {
+ try p.errTok(.initializer_overrides, l_brace);
+ try p.errTok(.previous_initializer, il.tok);
+ }
+ il.node = .none;
+ il.tok = l_brace;
+ return true;
+ }
+
+ var count: u64 = 0;
+ var warned_excess = false;
+ var is_str_init = false;
+ var index_hint: ?u64 = null;
+ while (true) : (count += 1) {
+ errdefer p.skipTo(.r_brace);
+
+ var first_tok = p.tok_i;
+ var cur_ty = init_ty;
+ var cur_il = il;
+ var designation = false;
+ var cur_index_hint: ?u64 = null;
+ while (true) {
+ if (p.eatToken(.l_bracket)) |l_bracket| {
+ if (!cur_ty.isArray()) {
+ try p.errStr(.invalid_array_designator, l_bracket, try p.typeStr(cur_ty));
+ return error.ParsingFailed;
+ }
+ const expr_tok = p.tok_i;
+ const index_res = try p.integerConstExpr(.gnu_folding_extension);
+ try p.expectClosing(l_bracket, .r_bracket);
+
+ if (index_res.val.tag == .unavailable) {
+ try p.errTok(.expected_integer_constant_expr, expr_tok);
+ return error.ParsingFailed;
+ } else if (index_res.val.compare(.lt, index_res.val.zero(), index_res.ty, p.comp)) {
+ try p.errExtra(.negative_array_designator, l_bracket + 1, .{
+ .signed = index_res.val.signExtend(index_res.ty, p.comp),
+ });
+ return error.ParsingFailed;
+ }
+
+ const max_len = cur_ty.arrayLen() orelse std.math.maxInt(usize);
+ if (index_res.val.data.int >= max_len) {
+ try p.errExtra(.oob_array_designator, l_bracket + 1, .{ .unsigned = index_res.val.data.int });
+ return error.ParsingFailed;
+ }
+ const checked = index_res.val.getInt(u64);
+ cur_index_hint = cur_index_hint orelse checked;
+
+ cur_il = try cur_il.find(p.gpa, checked);
+ cur_ty = cur_ty.elemType();
+ designation = true;
+ } else if (p.eatToken(.period)) |period| {
+ const field_tok = try p.expectIdentifier();
+ const field_str = p.tokSlice(field_tok);
+ const field_name = try p.comp.intern(field_str);
+ cur_ty = cur_ty.canonicalize(.standard);
+ if (!cur_ty.isRecord()) {
+ try p.errStr(.invalid_field_designator, period, try p.typeStr(cur_ty));
+ return error.ParsingFailed;
+ } else if (!cur_ty.hasField(field_name)) {
+ try p.errStr(.no_such_field_designator, period, field_str);
+ return error.ParsingFailed;
+ }
+
+ // TODO check if union already has field set
+ outer: while (true) {
+ for (cur_ty.data.record.fields, 0..) |f, i| {
+ if (f.isAnonymousRecord()) {
+ // Recurse into anonymous field if it has a field by the name.
+ if (!f.ty.hasField(field_name)) continue;
+ cur_ty = f.ty.canonicalize(.standard);
+ cur_il = try il.find(p.gpa, i);
+ cur_index_hint = cur_index_hint orelse i;
+ continue :outer;
+ }
+ if (field_name == f.name) {
+ cur_il = try cur_il.find(p.gpa, i);
+ cur_ty = f.ty;
+ cur_index_hint = cur_index_hint orelse i;
+ break :outer;
+ }
+ }
+ unreachable; // we already checked that the starting type has this field
+ }
+ designation = true;
+ } else break;
+ }
+ if (designation) index_hint = null;
+ defer index_hint = cur_index_hint orelse null;
+
+ if (designation) _ = try p.expectToken(.equal);
+
+ if (!designation and cur_ty.hasAttribute(.designated_init)) {
+ try p.err(.designated_init_needed);
+ }
+
+ var saw = false;
+ if (is_str_init and p.isStringInit(init_ty)) {
+ // discard further strings
+ var tmp_il = InitList{};
+ defer tmp_il.deinit(p.gpa);
+ saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
+ } else if (count == 0 and p.isStringInit(init_ty)) {
+ is_str_init = true;
+ saw = try p.initializerItem(il, init_ty);
+ } else if (is_scalar and count >= scalar_inits_needed) {
+ // discard further scalars
+ var tmp_il = InitList{};
+ defer tmp_il.deinit(p.gpa);
+ saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
+ } else if (p.tok_ids[p.tok_i] == .l_brace) {
+ if (designation) {
+ // designation overrides previous value, let existing mechanism handle it
+ saw = try p.initializerItem(cur_il, cur_ty);
+ } else if (try p.findAggregateInitializer(&cur_il, &cur_ty, &index_hint)) {
+ saw = try p.initializerItem(cur_il, cur_ty);
+ } else {
+ // discard further values
+ var tmp_il = InitList{};
+ defer tmp_il.deinit(p.gpa);
+ saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
+ if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
+ warned_excess = true;
+ }
+ } else single_item: {
+ first_tok = p.tok_i;
+ var res = try p.assignExpr();
+ saw = !res.empty(p);
+ if (!saw) break :single_item;
+
+ excess: {
+ if (index_hint) |*hint| {
+ if (try p.findScalarInitializerAt(&cur_il, &cur_ty, res.ty, first_tok, hint)) break :excess;
+ } else if (try p.findScalarInitializer(&cur_il, &cur_ty, res.ty, first_tok)) break :excess;
+
+ if (designation) break :excess;
+ if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
+ warned_excess = true;
+
+ break :single_item;
+ }
+
+ const arr = try p.coerceArrayInit(&res, first_tok, cur_ty);
+ if (!arr) try p.coerceInit(&res, first_tok, cur_ty);
+ if (cur_il.tok != 0) {
+ try p.errTok(.initializer_overrides, first_tok);
+ try p.errTok(.previous_initializer, cur_il.tok);
+ }
+ cur_il.node = res.node;
+ cur_il.tok = first_tok;
+ }
+
+ if (!saw) {
+ if (designation) {
+ try p.err(.expected_expr);
+ return error.ParsingFailed;
+ }
+ break;
+ } else if (count == 1) {
+ if (is_str_init) try p.errTok(.excess_str_init, first_tok);
+ if (is_scalar and !is_complex) try p.errTok(.excess_scalar_init, first_tok);
+ } else if (count == 2) {
+ if (is_scalar and is_complex) try p.errTok(.excess_scalar_init, first_tok);
+ }
+
+ if (p.eatToken(.comma) == null) break;
+ }
+ try p.expectClosing(l_brace, .r_brace);
+
+ if (is_complex and count == 1) { // count of 1 means we saw exactly 2 items in the initializer list
+ try p.errTok(.complex_component_init, l_brace);
+ }
+ if (is_scalar or is_str_init) return true;
+ if (il.tok != 0) {
+ try p.errTok(.initializer_overrides, l_brace);
+ try p.errTok(.previous_initializer, il.tok);
+ }
+ il.node = .none;
+ il.tok = l_brace;
+ return true;
+}
+
+/// Returns true if the value is unused.
+fn findScalarInitializerAt(p: *Parser, il: **InitList, ty: *Type, actual_ty: Type, first_tok: TokenIndex, start_index: *u64) Error!bool {
+ if (ty.isArray()) {
+ if (il.*.node != .none) return false;
+ start_index.* += 1;
+
+ const arr_ty = ty.*;
+ const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
+ if (elem_count == 0) {
+ try p.errTok(.empty_aggregate_init_braces, first_tok);
+ return error.ParsingFailed;
+ }
+ const elem_ty = arr_ty.elemType();
+ const arr_il = il.*;
+ if (start_index.* < elem_count) {
+ ty.* = elem_ty;
+ il.* = try arr_il.find(p.gpa, start_index.*);
+ _ = try p.findScalarInitializer(il, ty, actual_ty, first_tok);
+ return true;
+ }
+ return false;
+ } else if (ty.get(.@"struct")) |struct_ty| {
+ if (il.*.node != .none) return false;
+ start_index.* += 1;
+
+ const fields = struct_ty.data.record.fields;
+ if (fields.len == 0) {
+ try p.errTok(.empty_aggregate_init_braces, first_tok);
+ return error.ParsingFailed;
+ }
+ const struct_il = il.*;
+ if (start_index.* < fields.len) {
+ const field = fields[@intCast(start_index.*)];
+ ty.* = field.ty;
+ il.* = try struct_il.find(p.gpa, start_index.*);
+ _ = try p.findScalarInitializer(il, ty, actual_ty, first_tok);
+ return true;
+ }
+ return false;
+ } else if (ty.get(.@"union")) |_| {
+ return false;
+ }
+ return il.*.node == .none;
+}
+
+/// Returns true if the value is unused.
+fn findScalarInitializer(p: *Parser, il: **InitList, ty: *Type, actual_ty: Type, first_tok: TokenIndex) Error!bool {
+ if (ty.isArray() or ty.isComplex()) {
+ if (il.*.node != .none) return false;
+ const start_index = il.*.list.items.len;
+ var index = if (start_index != 0) il.*.list.items[start_index - 1].index else start_index;
+
+ const arr_ty = ty.*;
+ const elem_count: u64 = arr_ty.expectedInitListSize() orelse std.math.maxInt(u64);
+ if (elem_count == 0) {
+ try p.errTok(.empty_aggregate_init_braces, first_tok);
+ return error.ParsingFailed;
+ }
+ const elem_ty = arr_ty.elemType();
+ const arr_il = il.*;
+ while (index < elem_count) : (index += 1) {
+ ty.* = elem_ty;
+ il.* = try arr_il.find(p.gpa, index);
+ if (il.*.node == .none and actual_ty.eql(elem_ty, p.comp, false)) return true;
+ if (try p.findScalarInitializer(il, ty, actual_ty, first_tok)) return true;
+ }
+ return false;
+ } else if (ty.get(.@"struct")) |struct_ty| {
+ if (il.*.node != .none) return false;
+ if (actual_ty.eql(ty.*, p.pp.comp, false)) return true;
+ const start_index = il.*.list.items.len;
+ var index = if (start_index != 0) il.*.list.items[start_index - 1].index + 1 else start_index;
+
+ const fields = struct_ty.data.record.fields;
+ if (fields.len == 0) {
+ try p.errTok(.empty_aggregate_init_braces, first_tok);
+ return error.ParsingFailed;
+ }
+ const struct_il = il.*;
+ while (index < fields.len) : (index += 1) {
+ const field = fields[@intCast(index)];
+ ty.* = field.ty;
+ il.* = try struct_il.find(p.gpa, index);
+ if (il.*.node == .none and actual_ty.eql(field.ty, p.comp, false)) return true;
+ if (try p.findScalarInitializer(il, ty, actual_ty, first_tok)) return true;
+ }
+ return false;
+ } else if (ty.get(.@"union")) |union_ty| {
+ if (il.*.node != .none) return false;
+ if (actual_ty.eql(ty.*, p.pp.comp, false)) return true;
+ if (union_ty.data.record.fields.len == 0) {
+ try p.errTok(.empty_aggregate_init_braces, first_tok);
+ return error.ParsingFailed;
+ }
+ ty.* = union_ty.data.record.fields[0].ty;
+ il.* = try il.*.find(p.gpa, 0);
+ // if (il.*.node == .none and actual_ty.eql(ty, p.pp.comp, false)) return true;
+ if (try p.findScalarInitializer(il, ty, actual_ty, first_tok)) return true;
+ return false;
+ }
+ return il.*.node == .none;
+}
+
+fn findAggregateInitializer(p: *Parser, il: **InitList, ty: *Type, start_index: *?u64) Error!bool {
+ if (ty.isArray()) {
+ if (il.*.node != .none) return false;
+ const list_index = il.*.list.items.len;
+ const index = if (start_index.*) |*some| blk: {
+ some.* += 1;
+ break :blk some.*;
+ } else if (list_index != 0)
+ il.*.list.items[list_index - 1].index + 1
+ else
+ list_index;
+
+ const arr_ty = ty.*;
+ const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
+ const elem_ty = arr_ty.elemType();
+ if (index < elem_count) {
+ ty.* = elem_ty;
+ il.* = try il.*.find(p.gpa, index);
+ return true;
+ }
+ return false;
+ } else if (ty.get(.@"struct")) |struct_ty| {
+ if (il.*.node != .none) return false;
+ const list_index = il.*.list.items.len;
+ const index = if (start_index.*) |*some| blk: {
+ some.* += 1;
+ break :blk some.*;
+ } else if (list_index != 0)
+ il.*.list.items[list_index - 1].index + 1
+ else
+ list_index;
+
+ const field_count = struct_ty.data.record.fields.len;
+ if (index < field_count) {
+ ty.* = struct_ty.data.record.fields[@intCast(index)].ty;
+ il.* = try il.*.find(p.gpa, index);
+ return true;
+ }
+ return false;
+ } else if (ty.get(.@"union")) |union_ty| {
+ if (il.*.node != .none) return false;
+ if (start_index.*) |_| return false; // overrides
+ if (union_ty.data.record.fields.len == 0) return false;
+
+ ty.* = union_ty.data.record.fields[0].ty;
+ il.* = try il.*.find(p.gpa, 0);
+ return true;
+ } else {
+ try p.err(.too_many_scalar_init_braces);
+ return il.*.node == .none;
+ }
+}
+
+fn coerceArrayInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !bool {
+ if (!target.isArray()) return false;
+
+ const is_str_lit = p.nodeIs(item.node, .string_literal_expr);
+ if (!is_str_lit and !p.nodeIs(item.node, .compound_literal_expr) or !item.ty.isArray()) {
+ try p.errTok(.array_init_str, tok);
+ return true; // do not do further coercion
+ }
+
+ const target_spec = target.elemType().canonicalize(.standard).specifier;
+ const item_spec = item.ty.elemType().canonicalize(.standard).specifier;
+
+ const compatible = target.elemType().eql(item.ty.elemType(), p.comp, false) or
+ (is_str_lit and item_spec == .char and (target_spec == .uchar or target_spec == .schar)) or
+ (is_str_lit and item_spec == .uchar and (target_spec == .uchar or target_spec == .schar or target_spec == .char));
+ if (!compatible) {
+ const e_msg = " with array of type ";
+ try p.errStr(.incompatible_array_init, tok, try p.typePairStrExtra(target, e_msg, item.ty));
+ return true; // do not do further coercion
+ }
+
+ if (target.get(.array)) |arr_ty| {
+ assert(item.ty.specifier == .array);
+ var len = item.ty.arrayLen().?;
+ const array_len = arr_ty.arrayLen().?;
+ if (is_str_lit) {
+ // the null byte of a string can be dropped
+ if (len - 1 > array_len)
+ try p.errTok(.str_init_too_long, tok);
+ } else if (len > array_len) {
+ try p.errStr(
+ .arr_init_too_long,
+ tok,
+ try p.typePairStrExtra(target, " with array of type ", item.ty),
+ );
+ }
+ }
+ return true;
+}
+
+fn coerceInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !void {
+ if (target.is(.void)) return; // Do not do type coercion on excess items
+
+ const node = item.node;
+ try item.lvalConversion(p);
+ if (target.is(.auto_type)) {
+ if (p.getNode(node, .member_access_expr) orelse p.getNode(node, .member_access_ptr_expr)) |member_node| {
+ if (Tree.isBitfield(p.nodes.slice(), member_node)) try p.errTok(.auto_type_from_bitfield, tok);
+ }
+ return;
+ }
+
+ try item.coerce(p, target, tok, .init);
+}
+
+fn isStringInit(p: *Parser, ty: Type) bool {
+ if (!ty.isArray() or !ty.elemType().isInt()) return false;
+ var i = p.tok_i;
+ while (true) : (i += 1) {
+ switch (p.tok_ids[i]) {
+ .l_paren => {},
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ => return true,
+ else => return false,
+ }
+ }
+}
+
+/// Convert InitList into an AST
+fn convertInitList(p: *Parser, il: InitList, init_ty: Type) Error!NodeIndex {
+ const is_complex = init_ty.isComplex();
+ if (init_ty.isScalar() and !is_complex) {
+ if (il.node == .none) {
+ return p.addNode(.{ .tag = .default_init_expr, .ty = init_ty, .data = undefined });
+ }
+ return il.node;
+ } else if (init_ty.is(.variable_len_array)) {
+ return error.ParsingFailed; // vla invalid, reported earlier
+ } else if (init_ty.isArray() or is_complex) {
+ if (il.node != .none) {
+ return il.node;
+ }
+ const list_buf_top = p.list_buf.items.len;
+ defer p.list_buf.items.len = list_buf_top;
+
+ const elem_ty = init_ty.elemType();
+
+ const max_items: u64 = init_ty.expectedInitListSize() orelse std.math.maxInt(usize);
+ var start: u64 = 0;
+ for (il.list.items) |*init| {
+ if (init.index > start) {
+ const elem = try p.addNode(.{
+ .tag = .array_filler_expr,
+ .ty = elem_ty,
+ .data = .{ .int = init.index - start },
+ });
+ try p.list_buf.append(elem);
+ }
+ start = init.index + 1;
+
+ const elem = try p.convertInitList(init.list, elem_ty);
+ try p.list_buf.append(elem);
+ }
+
+ var arr_init_node: Tree.Node = .{
+ .tag = .array_init_expr_two,
+ .ty = init_ty,
+ .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+ };
+
+ if (init_ty.specifier == .incomplete_array) {
+ arr_init_node.ty.specifier = .array;
+ arr_init_node.ty.data.array.len = start;
+ } else if (init_ty.is(.incomplete_array)) {
+ const arr_ty = try p.arena.create(Type.Array);
+ arr_ty.* = .{ .elem = init_ty.elemType(), .len = start };
+ arr_init_node.ty = .{
+ .specifier = .array,
+ .data = .{ .array = arr_ty },
+ };
+ const attrs = init_ty.getAttributes();
+ arr_init_node.ty = try arr_init_node.ty.withAttributes(p.arena, attrs);
+ } else if (start < max_items) {
+ const elem = try p.addNode(.{
+ .tag = .array_filler_expr,
+ .ty = elem_ty,
+ .data = .{ .int = max_items - start },
+ });
+ try p.list_buf.append(elem);
+ }
+
+ const items = p.list_buf.items[list_buf_top..];
+ switch (items.len) {
+ 0 => {},
+ 1 => arr_init_node.data.bin.lhs = items[0],
+ 2 => arr_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
+ else => {
+ arr_init_node.tag = .array_init_expr;
+ arr_init_node.data = .{ .range = try p.addList(items) };
+ },
+ }
+ return try p.addNode(arr_init_node);
+ } else if (init_ty.get(.@"struct")) |struct_ty| {
+ assert(!struct_ty.hasIncompleteSize());
+ if (il.node != .none) {
+ return il.node;
+ }
+
+ const list_buf_top = p.list_buf.items.len;
+ defer p.list_buf.items.len = list_buf_top;
+
+ var init_index: usize = 0;
+ for (struct_ty.data.record.fields, 0..) |f, i| {
+ if (init_index < il.list.items.len and il.list.items[init_index].index == i) {
+ const item = try p.convertInitList(il.list.items[init_index].list, f.ty);
+ try p.list_buf.append(item);
+ init_index += 1;
+ } else {
+ const item = try p.addNode(.{ .tag = .default_init_expr, .ty = f.ty, .data = undefined });
+ try p.list_buf.append(item);
+ }
+ }
+
+ var struct_init_node: Tree.Node = .{
+ .tag = .struct_init_expr_two,
+ .ty = init_ty,
+ .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+ };
+ const items = p.list_buf.items[list_buf_top..];
+ switch (items.len) {
+ 0 => {},
+ 1 => struct_init_node.data.bin.lhs = items[0],
+ 2 => struct_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
+ else => {
+ struct_init_node.tag = .struct_init_expr;
+ struct_init_node.data = .{ .range = try p.addList(items) };
+ },
+ }
+ return try p.addNode(struct_init_node);
+ } else if (init_ty.get(.@"union")) |union_ty| {
+ if (il.node != .none) {
+ return il.node;
+ }
+
+ var union_init_node: Tree.Node = .{
+ .tag = .union_init_expr,
+ .ty = init_ty,
+ .data = .{ .union_init = .{ .field_index = 0, .node = .none } },
+ };
+ if (union_ty.data.record.fields.len == 0) {
+ // do nothing for empty unions
+ } else if (il.list.items.len == 0) {
+ union_init_node.data.union_init.node = try p.addNode(.{
+ .tag = .default_init_expr,
+ .ty = init_ty,
+ .data = undefined,
+ });
+ } else {
+ const init = il.list.items[0];
+ const index: u32 = @truncate(init.index);
+ const field_ty = union_ty.data.record.fields[index].ty;
+ union_init_node.data.union_init = .{
+ .field_index = index,
+ .node = try p.convertInitList(init.list, field_ty),
+ };
+ }
+ return try p.addNode(union_init_node);
+ } else {
+ return error.ParsingFailed; // initializer target is invalid, reported earlier
+ }
+}
+
+fn msvcAsmStmt(p: *Parser) Error!?NodeIndex {
+ return p.todo("MSVC assembly statements");
+}
+
+/// asmOperand : ('[' IDENTIFIER ']')? asmStr '(' expr ')'
+fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *NodeList, exprs: *NodeList) Error!void {
+ if (p.eatToken(.l_bracket)) |l_bracket| {
+ const ident = (try p.eatIdentifier()) orelse {
+ try p.err(.expected_identifier);
+ return error.ParsingFailed;
+ };
+ try names.append(ident);
+ try p.expectClosing(l_bracket, .r_bracket);
+ } else {
+ try names.append(null);
+ }
+ const constraint = try p.asmStr();
+ try constraints.append(constraint.node);
+
+ const l_paren = p.eatToken(.l_paren) orelse {
+ try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .l_paren } });
+ return error.ParsingFailed;
+ };
+ const res = try p.expr();
+ try p.expectClosing(l_paren, .r_paren);
+ try res.expect(p);
+ try exprs.append(res.node);
+}
+
+/// gnuAsmStmt
+/// : asmStr
+/// | asmStr ':' asmOperand*
+/// | asmStr ':' asmOperand* ':' asmOperand*
+/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)*
+/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)* : IDENTIFIER (',' IDENTIFIER)*
+fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, l_paren: TokenIndex) Error!NodeIndex {
+ const asm_str = try p.asmStr();
+ try p.checkAsmStr(asm_str.val, l_paren);
+
+ if (p.tok_ids[p.tok_i] == .r_paren) {
+ return p.addNode(.{
+ .tag = .gnu_asm_simple,
+ .ty = .{ .specifier = .void },
+ .data = .{ .un = asm_str.node },
+ });
+ }
+
+ const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names
+ const bytes_needed = expected_items * @sizeOf(?TokenIndex) + expected_items * 3 * @sizeOf(NodeIndex);
+
+ var stack_fallback = std.heap.stackFallback(bytes_needed, p.comp.gpa);
+ const allocator = stack_fallback.get();
+
+ // TODO: Consider using a TokenIndex of 0 instead of null if we need to store the names in the tree
+ var names = std.ArrayList(?TokenIndex).initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
+ defer names.deinit();
+ var constraints = NodeList.initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
+ defer constraints.deinit();
+ var exprs = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
+ defer exprs.deinit();
+ var clobbers = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
+ defer clobbers.deinit();
+
+ // Outputs
+ var ate_extra_colon = false;
+ if (p.eatToken(.colon) orelse p.eatToken(.colon_colon)) |tok_i| {
+ ate_extra_colon = p.tok_ids[tok_i] == .colon_colon;
+ if (!ate_extra_colon) {
+ if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
+ while (true) {
+ try p.asmOperand(&names, &constraints, &exprs);
+ if (p.eatToken(.comma) == null) break;
+ }
+ }
+ }
+ }
+
+ const num_outputs = names.items.len;
+
+ // Inputs
+ if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
+ if (ate_extra_colon) {
+ ate_extra_colon = false;
+ } else {
+ ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
+ p.tok_i += 1;
+ }
+ if (!ate_extra_colon) {
+ if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
+ while (true) {
+ try p.asmOperand(&names, &constraints, &exprs);
+ if (p.eatToken(.comma) == null) break;
+ }
+ }
+ }
+ }
+ std.debug.assert(names.items.len == constraints.items.len and constraints.items.len == exprs.items.len);
+ const num_inputs = names.items.len - num_outputs;
+ _ = num_inputs;
+
+ // Clobbers
+ if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
+ if (ate_extra_colon) {
+ ate_extra_colon = false;
+ } else {
+ ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
+ p.tok_i += 1;
+ }
+ if (!ate_extra_colon and p.tok_ids[p.tok_i].isStringLiteral()) {
+ while (true) {
+ const clobber = try p.asmStr();
+ try clobbers.append(clobber.node);
+ if (p.eatToken(.comma) == null) break;
+ }
+ }
+ }
+
+ if (!quals.goto and (p.tok_ids[p.tok_i] != .r_paren or ate_extra_colon)) {
+ try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .r_paren } });
+ return error.ParsingFailed;
+ }
+
+ // Goto labels
+ var num_labels: u32 = 0;
+ if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon) {
+ if (!ate_extra_colon) {
+ p.tok_i += 1;
+ }
+ while (true) {
+ const ident = (try p.eatIdentifier()) orelse {
+ try p.err(.expected_identifier);
+ return error.ParsingFailed;
+ };
+ const ident_str = p.tokSlice(ident);
+ const label = p.findLabel(ident_str) orelse blk: {
+ try p.labels.append(.{ .unresolved_goto = ident });
+ break :blk ident;
+ };
+ try names.append(ident);
+
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = .{ .specifier = .void };
+ const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
+
+ const label_addr_node = try p.addNode(.{
+ .tag = .addr_of_label,
+ .data = .{ .decl_ref = label },
+ .ty = result_ty,
+ });
+ try exprs.append(label_addr_node);
+
+ num_labels += 1;
+ if (p.eatToken(.comma) == null) break;
+ }
+ } else if (quals.goto) {
+ try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .colon } });
+ return error.ParsingFailed;
+ }
+
+ // TODO: validate and insert into AST
+ return .none;
+}
+
+fn checkAsmStr(p: *Parser, asm_str: Value, tok: TokenIndex) !void {
+ if (!p.comp.langopts.gnu_asm) {
+ const str = asm_str.data.bytes;
+ if (str.len() > 1) {
+ // Empty string (just a NUL byte) is ok because it does not emit any assembly
+ try p.errTok(.gnu_asm_disabled, tok);
+ }
+ }
+}
+
+/// assembly
+/// : keyword_asm asmQual* '(' asmStr ')'
+/// | keyword_asm asmQual* '(' gnuAsmStmt ')'
+/// | keyword_asm msvcAsmStmt
+fn assembly(p: *Parser, kind: enum { global, decl_label, stmt }) Error!?NodeIndex {
+ const asm_tok = p.tok_i;
+ switch (p.tok_ids[p.tok_i]) {
+ .keyword_asm => {
+ try p.err(.extension_token_used);
+ p.tok_i += 1;
+ },
+ .keyword_asm1, .keyword_asm2 => p.tok_i += 1,
+ else => return null,
+ }
+
+ if (!p.tok_ids[p.tok_i].canOpenGCCAsmStmt()) {
+ return p.msvcAsmStmt();
+ }
+
+ var quals: Tree.GNUAssemblyQualifiers = .{};
+ while (true) : (p.tok_i += 1) switch (p.tok_ids[p.tok_i]) {
+ .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
+ if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "volatile");
+ if (quals.@"volatile") try p.errStr(.duplicate_asm_qual, p.tok_i, "volatile");
+ quals.@"volatile" = true;
+ },
+ .keyword_inline, .keyword_inline1, .keyword_inline2 => {
+ if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "inline");
+ if (quals.@"inline") try p.errStr(.duplicate_asm_qual, p.tok_i, "inline");
+ quals.@"inline" = true;
+ },
+ .keyword_goto => {
+ if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "goto");
+ if (quals.goto) try p.errStr(.duplicate_asm_qual, p.tok_i, "goto");
+ quals.goto = true;
+ },
+ else => break,
+ };
+
+ const l_paren = try p.expectToken(.l_paren);
+ var result_node: NodeIndex = .none;
+ switch (kind) {
+ .decl_label => {
+ const asm_str = try p.asmStr();
+ const str = asm_str.val.data.bytes.trim(1); // remove null-terminator
+ const attr = Attribute{ .tag = .asm_label, .args = .{ .asm_label = .{ .name = str } }, .syntax = .keyword };
+ try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = asm_tok });
+ },
+ .global => {
+ const asm_str = try p.asmStr();
+ try p.checkAsmStr(asm_str.val, l_paren);
+ result_node = try p.addNode(.{
+ .tag = .file_scope_asm,
+ .ty = .{ .specifier = .void },
+ .data = .{ .decl = .{ .name = asm_tok, .node = asm_str.node } },
+ });
+ },
+ .stmt => result_node = try p.gnuAsmStmt(quals, l_paren),
+ }
+ try p.expectClosing(l_paren, .r_paren);
+
+ if (kind != .decl_label) _ = try p.expectToken(.semicolon);
+ return result_node;
+}
+
+/// Same as stringLiteral but errors on unicode and wide string literals
+fn asmStr(p: *Parser) Error!Result {
+ var i = p.tok_i;
+ while (true) : (i += 1) switch (p.tok_ids[i]) {
+ .string_literal => {},
+ .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32 => {
+ try p.errStr(.invalid_asm_str, p.tok_i, "unicode");
+ return error.ParsingFailed;
+ },
+ .string_literal_wide => {
+ try p.errStr(.invalid_asm_str, p.tok_i, "wide");
+ return error.ParsingFailed;
+ },
+ else => break,
+ };
+ return try p.stringLiteral();
+}
+
+// ====== statements ======
+
+/// stmt
+/// : labeledStmt
+/// | compoundStmt
+/// | keyword_if '(' expr ')' stmt (keyword_else stmt)?
+/// | keyword_switch '(' expr ')' stmt
+/// | keyword_while '(' expr ')' stmt
+/// | keyword_do stmt while '(' expr ')' ';'
+/// | keyword_for '(' (decl | expr? ';') expr? ';' expr? ')' stmt
+/// | keyword_goto (IDENTIFIER | ('*' expr)) ';'
+/// | keyword_continue ';'
+/// | keyword_break ';'
+/// | keyword_return expr? ';'
+/// | assembly ';'
+/// | expr? ';'
+fn stmt(p: *Parser) Error!NodeIndex {
+ if (try p.labeledStmt()) |some| return some;
+ if (try p.compoundStmt(false, null)) |some| return some;
+ if (p.eatToken(.keyword_if)) |_| {
+ const l_paren = try p.expectToken(.l_paren);
+ const cond_tok = p.tok_i;
+ var cond = try p.expr();
+ try cond.expect(p);
+ try cond.lvalConversion(p);
+ try cond.usualUnaryConversion(p, cond_tok);
+ if (!cond.ty.isScalar())
+ try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+ try cond.saveValue(p);
+ try p.expectClosing(l_paren, .r_paren);
+
+ const then = try p.stmt();
+ const @"else" = if (p.eatToken(.keyword_else)) |_| try p.stmt() else .none;
+
+ if (then != .none and @"else" != .none)
+ return try p.addNode(.{
+ .tag = .if_then_else_stmt,
+ .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then, @"else" })).start } },
+ })
+ else
+ return try p.addNode(.{
+ .tag = .if_then_stmt,
+ .data = .{ .bin = .{ .lhs = cond.node, .rhs = then } },
+ });
+ }
+ if (p.eatToken(.keyword_switch)) |_| {
+ const l_paren = try p.expectToken(.l_paren);
+ const cond_tok = p.tok_i;
+ var cond = try p.expr();
+ try cond.expect(p);
+ try cond.lvalConversion(p);
+ try cond.usualUnaryConversion(p, cond_tok);
+
+ if (!cond.ty.isInt())
+ try p.errStr(.statement_int, l_paren + 1, try p.typeStr(cond.ty));
+ try cond.saveValue(p);
+ try p.expectClosing(l_paren, .r_paren);
+
+ const old_switch = p.@"switch";
+ var @"switch" = Switch{
+ .ranges = std.ArrayList(Switch.Range).init(p.gpa),
+ .ty = cond.ty,
+ };
+ p.@"switch" = &@"switch";
+ defer {
+ @"switch".ranges.deinit();
+ p.@"switch" = old_switch;
+ }
+
+ const body = try p.stmt();
+
+ return try p.addNode(.{
+ .tag = .switch_stmt,
+ .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
+ });
+ }
+ if (p.eatToken(.keyword_while)) |_| {
+ const l_paren = try p.expectToken(.l_paren);
+ const cond_tok = p.tok_i;
+ var cond = try p.expr();
+ try cond.expect(p);
+ try cond.lvalConversion(p);
+ try cond.usualUnaryConversion(p, cond_tok);
+ if (!cond.ty.isScalar())
+ try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+ try cond.saveValue(p);
+ try p.expectClosing(l_paren, .r_paren);
+
+ const body = body: {
+ const old_loop = p.in_loop;
+ p.in_loop = true;
+ defer p.in_loop = old_loop;
+ break :body try p.stmt();
+ };
+
+ return try p.addNode(.{
+ .tag = .while_stmt,
+ .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
+ });
+ }
+ if (p.eatToken(.keyword_do)) |_| {
+ const body = body: {
+ const old_loop = p.in_loop;
+ p.in_loop = true;
+ defer p.in_loop = old_loop;
+ break :body try p.stmt();
+ };
+
+ _ = try p.expectToken(.keyword_while);
+ const l_paren = try p.expectToken(.l_paren);
+ const cond_tok = p.tok_i;
+ var cond = try p.expr();
+ try cond.expect(p);
+ try cond.lvalConversion(p);
+ try cond.usualUnaryConversion(p, cond_tok);
+
+ if (!cond.ty.isScalar())
+ try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+ try cond.saveValue(p);
+ try p.expectClosing(l_paren, .r_paren);
+
+ _ = try p.expectToken(.semicolon);
+ return try p.addNode(.{
+ .tag = .do_while_stmt,
+ .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
+ });
+ }
+ if (p.eatToken(.keyword_for)) |_| {
+ try p.syms.pushScope(p);
+ defer p.syms.popScope();
+ const decl_buf_top = p.decl_buf.items.len;
+ defer p.decl_buf.items.len = decl_buf_top;
+
+ const l_paren = try p.expectToken(.l_paren);
+ const got_decl = try p.decl();
+
+ // for (init
+ const init_start = p.tok_i;
+ var err_start = p.comp.diag.list.items.len;
+ var init = if (!got_decl) try p.expr() else Result{};
+ try init.saveValue(p);
+ try init.maybeWarnUnused(p, init_start, err_start);
+ if (!got_decl) _ = try p.expectToken(.semicolon);
+
+ // for (init; cond
+ const cond_tok = p.tok_i;
+ var cond = try p.expr();
+ if (cond.node != .none) {
+ try cond.lvalConversion(p);
+ try cond.usualUnaryConversion(p, cond_tok);
+ if (!cond.ty.isScalar())
+ try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+ }
+ try cond.saveValue(p);
+ _ = try p.expectToken(.semicolon);
+
+ // for (init; cond; incr
+ const incr_start = p.tok_i;
+ err_start = p.comp.diag.list.items.len;
+ var incr = try p.expr();
+ try incr.maybeWarnUnused(p, incr_start, err_start);
+ try incr.saveValue(p);
+ try p.expectClosing(l_paren, .r_paren);
+
+ const body = body: {
+ const old_loop = p.in_loop;
+ p.in_loop = true;
+ defer p.in_loop = old_loop;
+ break :body try p.stmt();
+ };
+
+ if (got_decl) {
+ const start = (try p.addList(p.decl_buf.items[decl_buf_top..])).start;
+ const end = (try p.addList(&.{ cond.node, incr.node, body })).end;
+
+ return try p.addNode(.{
+ .tag = .for_decl_stmt,
+ .data = .{ .range = .{ .start = start, .end = end } },
+ });
+ } else if (init.node == .none and cond.node == .none and incr.node == .none) {
+ return try p.addNode(.{
+ .tag = .forever_stmt,
+ .data = .{ .un = body },
+ });
+ } else return try p.addNode(.{ .tag = .for_stmt, .data = .{ .if3 = .{
+ .cond = body,
+ .body = (try p.addList(&.{ init.node, cond.node, incr.node })).start,
+ } } });
+ }
+ if (p.eatToken(.keyword_goto)) |goto_tok| {
+ if (p.eatToken(.asterisk)) |_| {
+ const expr_tok = p.tok_i;
+ var e = try p.expr();
+ try e.expect(p);
+ try e.lvalConversion(p);
+ p.computed_goto_tok = p.computed_goto_tok orelse goto_tok;
+ if (!e.ty.isPtr()) {
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = .{ .specifier = .void, .qual = .{ .@"const" = true } };
+ const result_ty = Type{
+ .specifier = .pointer,
+ .data = .{ .sub_type = elem_ty },
+ };
+ if (!e.ty.isInt()) {
+ try p.errStr(.incompatible_arg, expr_tok, try p.typePairStrExtra(e.ty, " to parameter of incompatible type ", result_ty));
+ return error.ParsingFailed;
+ }
+ if (e.val.isZero()) {
+ try e.nullCast(p, result_ty);
+ } else {
+ try p.errStr(.implicit_int_to_ptr, expr_tok, try p.typePairStrExtra(e.ty, " to ", result_ty));
+ try e.ptrCast(p, result_ty);
+ }
+ }
+
+ try e.un(p, .computed_goto_stmt);
+ _ = try p.expectToken(.semicolon);
+ return e.node;
+ }
+ const name_tok = try p.expectIdentifier();
+ const str = p.tokSlice(name_tok);
+ if (p.findLabel(str) == null) {
+ try p.labels.append(.{ .unresolved_goto = name_tok });
+ }
+ _ = try p.expectToken(.semicolon);
+ return try p.addNode(.{
+ .tag = .goto_stmt,
+ .data = .{ .decl_ref = name_tok },
+ });
+ }
+ if (p.eatToken(.keyword_continue)) |cont| {
+ if (!p.in_loop) try p.errTok(.continue_not_in_loop, cont);
+ _ = try p.expectToken(.semicolon);
+ return try p.addNode(.{ .tag = .continue_stmt, .data = undefined });
+ }
+ if (p.eatToken(.keyword_break)) |br| {
+ if (!p.in_loop and p.@"switch" == null) try p.errTok(.break_not_in_loop_or_switch, br);
+ _ = try p.expectToken(.semicolon);
+ return try p.addNode(.{ .tag = .break_stmt, .data = undefined });
+ }
+ if (try p.returnStmt()) |some| return some;
+ if (try p.assembly(.stmt)) |some| return some;
+
+ const expr_start = p.tok_i;
+ const err_start = p.comp.diag.list.items.len;
+
+ const e = try p.expr();
+ if (e.node != .none) {
+ _ = try p.expectToken(.semicolon);
+ try e.maybeWarnUnused(p, expr_start, err_start);
+ return e.node;
+ }
+
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ try p.attributeSpecifier();
+
+ if (p.eatToken(.semicolon)) |_| {
+ var null_node: Tree.Node = .{ .tag = .null_stmt, .data = undefined };
+ null_node.ty = try Attribute.applyStatementAttributes(p, null_node.ty, expr_start, attr_buf_top);
+ return p.addNode(null_node);
+ }
+
+ try p.err(.expected_stmt);
+ return error.ParsingFailed;
+}
+
+/// labeledStmt
+/// : IDENTIFIER ':' stmt
+/// | keyword_case integerConstExpr ':' stmt
+/// | keyword_default ':' stmt
+fn labeledStmt(p: *Parser) Error!?NodeIndex {
+ if ((p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) and p.tok_ids[p.tok_i + 1] == .colon) {
+ const name_tok = p.expectIdentifier() catch unreachable;
+ const str = p.tokSlice(name_tok);
+ if (p.findLabel(str)) |some| {
+ try p.errStr(.duplicate_label, name_tok, str);
+ try p.errStr(.previous_label, some, str);
+ } else {
+ p.label_count += 1;
+ try p.labels.append(.{ .label = name_tok });
+ var i: usize = 0;
+ while (i < p.labels.items.len) {
+ if (p.labels.items[i] == .unresolved_goto and
+ mem.eql(u8, p.tokSlice(p.labels.items[i].unresolved_goto), str))
+ {
+ _ = p.labels.swapRemove(i);
+ } else i += 1;
+ }
+ }
+
+ p.tok_i += 1;
+ const attr_buf_top = p.attr_buf.len;
+ defer p.attr_buf.len = attr_buf_top;
+ try p.attributeSpecifier();
+
+ var labeled_stmt = Tree.Node{
+ .tag = .labeled_stmt,
+ .data = .{ .decl = .{ .name = name_tok, .node = try p.stmt() } },
+ };
+ labeled_stmt.ty = try Attribute.applyLabelAttributes(p, labeled_stmt.ty, attr_buf_top);
+ return try p.addNode(labeled_stmt);
+ } else if (p.eatToken(.keyword_case)) |case| {
+ const first_item = try p.integerConstExpr(.gnu_folding_extension);
+ const ellipsis = p.tok_i;
+ const second_item = if (p.eatToken(.ellipsis) != null) blk: {
+ try p.errTok(.gnu_switch_range, ellipsis);
+ break :blk try p.integerConstExpr(.gnu_folding_extension);
+ } else null;
+ _ = try p.expectToken(.colon);
+
+ if (p.@"switch") |some| check: {
+ if (some.ty.hasIncompleteSize()) break :check; // error already reported for incomplete size
+
+ const first = first_item.val;
+ const last = if (second_item) |second| second.val else first;
+ if (first.tag == .unavailable) {
+ try p.errTok(.case_val_unavailable, case + 1);
+ break :check;
+ } else if (last.tag == .unavailable) {
+ try p.errTok(.case_val_unavailable, ellipsis + 1);
+ break :check;
+ } else if (last.compare(.lt, first, some.ty, p.comp)) {
+ try p.errTok(.empty_case_range, case + 1);
+ break :check;
+ }
+
+ // TODO cast to target type
+ const prev = (try some.add(p.comp, first, last, case + 1)) orelse break :check;
+
+ // TODO check which value was already handled
+ if (some.ty.isUnsignedInt(p.comp)) {
+ try p.errExtra(.duplicate_switch_case_unsigned, case + 1, .{
+ .unsigned = first.data.int,
+ });
+ } else {
+ try p.errExtra(.duplicate_switch_case_signed, case + 1, .{
+ .signed = first.signExtend(some.ty, p.comp),
+ });
+ }
+ try p.errTok(.previous_case, prev.tok);
+ } else {
+ try p.errStr(.case_not_in_switch, case, "case");
+ }
+
+ const s = try p.stmt();
+ if (second_item) |some| return try p.addNode(.{
+ .tag = .case_range_stmt,
+ .data = .{ .if3 = .{ .cond = s, .body = (try p.addList(&.{ first_item.node, some.node })).start } },
+ }) else return try p.addNode(.{
+ .tag = .case_stmt,
+ .data = .{ .bin = .{ .lhs = first_item.node, .rhs = s } },
+ });
+ } else if (p.eatToken(.keyword_default)) |default| {
+ _ = try p.expectToken(.colon);
+ const s = try p.stmt();
+ const node = try p.addNode(.{
+ .tag = .default_stmt,
+ .data = .{ .un = s },
+ });
+ const @"switch" = p.@"switch" orelse {
+ try p.errStr(.case_not_in_switch, default, "default");
+ return node;
+ };
+ if (@"switch".default) |previous| {
+ try p.errTok(.multiple_default, default);
+ try p.errTok(.previous_case, previous);
+ } else {
+ @"switch".default = default;
+ }
+ return node;
+ } else return null;
+}
+
+const StmtExprState = struct {
+ last_expr_tok: TokenIndex = 0,
+ last_expr_res: Result = .{ .ty = .{ .specifier = .void } },
+};
+
+/// compoundStmt : '{' ( decl | keyword_extension decl | staticAssert | stmt)* '}'
+fn compoundStmt(p: *Parser, is_fn_body: bool, stmt_expr_state: ?*StmtExprState) Error!?NodeIndex {
+ const l_brace = p.eatToken(.l_brace) orelse return null;
+
+ const decl_buf_top = p.decl_buf.items.len;
+ defer p.decl_buf.items.len = decl_buf_top;
+
+ // the parameters of a function are in the same scope as the body
+ if (!is_fn_body) try p.syms.pushScope(p);
+ defer if (!is_fn_body) p.syms.popScope();
+
+ var noreturn_index: ?TokenIndex = null;
+ var noreturn_label_count: u32 = 0;
+
+ while (p.eatToken(.r_brace) == null) : (_ = try p.pragma()) {
+ if (stmt_expr_state) |state| state.* = .{};
+ if (try p.parseOrNextStmt(staticAssert, l_brace)) continue;
+ if (try p.parseOrNextStmt(decl, l_brace)) continue;
+ if (p.eatToken(.keyword_extension)) |ext| {
+ const saved_extension = p.extension_suppressed;
+ defer p.extension_suppressed = saved_extension;
+ p.extension_suppressed = true;
+
+ if (try p.parseOrNextStmt(decl, l_brace)) continue;
+ p.tok_i = ext;
+ }
+ const stmt_tok = p.tok_i;
+ const s = p.stmt() catch |er| switch (er) {
+ error.ParsingFailed => {
+ try p.nextStmt(l_brace);
+ continue;
+ },
+ else => |e| return e,
+ };
+ if (s == .none) continue;
+ if (stmt_expr_state) |state| {
+ state.* = .{
+ .last_expr_tok = stmt_tok,
+ .last_expr_res = .{
+ .node = s,
+ .ty = p.nodes.items(.ty)[@intFromEnum(s)],
+ },
+ };
+ }
+ try p.decl_buf.append(s);
+
+ if (noreturn_index == null and p.nodeIsNoreturn(s) == .yes) {
+ noreturn_index = p.tok_i;
+ noreturn_label_count = p.label_count;
+ }
+ switch (p.nodes.items(.tag)[@intFromEnum(s)]) {
+ .case_stmt, .default_stmt, .labeled_stmt => noreturn_index = null,
+ else => {},
+ }
+ }
+
+ if (noreturn_index) |some| {
+ // if new labels were defined we cannot be certain that the code is unreachable
+ if (some != p.tok_i - 1 and noreturn_label_count == p.label_count) try p.errTok(.unreachable_code, some);
+ }
+ if (is_fn_body) {
+ const last_noreturn = if (p.decl_buf.items.len == decl_buf_top)
+ .no
+ else
+ p.nodeIsNoreturn(p.decl_buf.items[p.decl_buf.items.len - 1]);
+
+ if (last_noreturn != .yes) {
+ const ret_ty = p.func.ty.?.returnType();
+ var return_zero = false;
+ if (last_noreturn == .no and !ret_ty.is(.void) and !ret_ty.isFunc() and !ret_ty.isArray()) {
+ const func_name = p.tokSlice(p.func.name);
+ const interned_name = try p.comp.intern(func_name);
+ if (interned_name == p.string_ids.main_id and ret_ty.is(.int)) {
+ return_zero = true;
+ } else {
+ try p.errStr(.func_does_not_return, p.tok_i - 1, func_name);
+ }
+ }
+ try p.decl_buf.append(try p.addNode(.{ .tag = .implicit_return, .ty = p.func.ty.?.returnType(), .data = .{ .return_zero = return_zero } }));
+ }
+ if (p.func.ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
+ if (p.func.pretty_ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
+ }
+
+ var node: Tree.Node = .{
+ .tag = .compound_stmt_two,
+ .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+ };
+ const statements = p.decl_buf.items[decl_buf_top..];
+ switch (statements.len) {
+ 0 => {},
+ 1 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = .none } },
+ 2 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = statements[1] } },
+ else => {
+ node.tag = .compound_stmt;
+ node.data = .{ .range = try p.addList(statements) };
+ },
+ }
+ return try p.addNode(node);
+}
+
+const NoreturnKind = enum { no, yes, complex };
+
+fn nodeIsNoreturn(p: *Parser, node: NodeIndex) NoreturnKind {
+ switch (p.nodes.items(.tag)[@intFromEnum(node)]) {
+ .break_stmt, .continue_stmt, .return_stmt => return .yes,
+ .if_then_else_stmt => {
+ const data = p.data.items[p.nodes.items(.data)[@intFromEnum(node)].if3.body..];
+ const then_type = p.nodeIsNoreturn(data[0]);
+ const else_type = p.nodeIsNoreturn(data[1]);
+ if (then_type == .complex or else_type == .complex) return .complex;
+ if (then_type == .yes and else_type == .yes) return .yes;
+ return .no;
+ },
+ .compound_stmt_two => {
+ const data = p.nodes.items(.data)[@intFromEnum(node)];
+ if (data.bin.rhs != .none) return p.nodeIsNoreturn(data.bin.rhs);
+ if (data.bin.lhs != .none) return p.nodeIsNoreturn(data.bin.lhs);
+ return .no;
+ },
+ .compound_stmt => {
+ const data = p.nodes.items(.data)[@intFromEnum(node)];
+ return p.nodeIsNoreturn(p.data.items[data.range.end - 1]);
+ },
+ .labeled_stmt => {
+ const data = p.nodes.items(.data)[@intFromEnum(node)];
+ return p.nodeIsNoreturn(data.decl.node);
+ },
+ .switch_stmt => {
+ const data = p.nodes.items(.data)[@intFromEnum(node)];
+ if (data.bin.rhs == .none) return .complex;
+ if (p.nodeIsNoreturn(data.bin.rhs) == .yes) return .yes;
+ return .complex;
+ },
+ else => return .no,
+ }
+}
+
+fn parseOrNextStmt(p: *Parser, comptime func: fn (*Parser) Error!bool, l_brace: TokenIndex) !bool {
+ return func(p) catch |er| switch (er) {
+ error.ParsingFailed => {
+ try p.nextStmt(l_brace);
+ return true;
+ },
+ else => |e| return e,
+ };
+}
+
+fn nextStmt(p: *Parser, l_brace: TokenIndex) !void {
+ var parens: u32 = 0;
+ while (p.tok_i < p.tok_ids.len) : (p.tok_i += 1) {
+ switch (p.tok_ids[p.tok_i]) {
+ .l_paren, .l_brace, .l_bracket => parens += 1,
+ .r_paren, .r_bracket => if (parens != 0) {
+ parens -= 1;
+ },
+ .r_brace => if (parens == 0)
+ return
+ else {
+ parens -= 1;
+ },
+ .semicolon,
+ .keyword_for,
+ .keyword_while,
+ .keyword_do,
+ .keyword_if,
+ .keyword_goto,
+ .keyword_switch,
+ .keyword_case,
+ .keyword_default,
+ .keyword_continue,
+ .keyword_break,
+ .keyword_return,
+ .keyword_typedef,
+ .keyword_extern,
+ .keyword_static,
+ .keyword_auto,
+ .keyword_register,
+ .keyword_thread_local,
+ .keyword_c23_thread_local,
+ .keyword_inline,
+ .keyword_inline1,
+ .keyword_inline2,
+ .keyword_noreturn,
+ .keyword_void,
+ .keyword_bool,
+ .keyword_c23_bool,
+ .keyword_char,
+ .keyword_short,
+ .keyword_int,
+ .keyword_long,
+ .keyword_signed,
+ .keyword_unsigned,
+ .keyword_float,
+ .keyword_double,
+ .keyword_complex,
+ .keyword_atomic,
+ .keyword_enum,
+ .keyword_struct,
+ .keyword_union,
+ .keyword_alignas,
+ .keyword_c23_alignas,
+ .keyword_typeof,
+ .keyword_typeof1,
+ .keyword_typeof2,
+ .keyword_extension,
+ => if (parens == 0) return,
+ .keyword_pragma => p.skipToPragmaSentinel(),
+ else => {},
+ }
+ }
+ p.tok_i -= 1; // So we can consume EOF
+ try p.expectClosing(l_brace, .r_brace);
+ unreachable;
+}
+
+fn returnStmt(p: *Parser) Error!?NodeIndex {
+ const ret_tok = p.eatToken(.keyword_return) orelse return null;
+
+ const e_tok = p.tok_i;
+ var e = try p.expr();
+ _ = try p.expectToken(.semicolon);
+ const ret_ty = p.func.ty.?.returnType();
+
+ if (p.func.ty.?.hasAttribute(.noreturn)) {
+ try p.errStr(.invalid_noreturn, e_tok, p.tokSlice(p.func.name));
+ }
+
+ if (e.node == .none) {
+ if (!ret_ty.is(.void)) try p.errStr(.func_should_return, ret_tok, p.tokSlice(p.func.name));
+ return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
+ } else if (ret_ty.is(.void)) {
+ try p.errStr(.void_func_returns_value, e_tok, p.tokSlice(p.func.name));
+ return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
+ }
+
+ try e.lvalConversion(p);
+ try e.coerce(p, ret_ty, e_tok, .ret);
+
+ try e.saveValue(p);
+ return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
+}
+
+// ====== expressions ======
+
+pub fn macroExpr(p: *Parser) Compilation.Error!bool {
+ const res = p.condExpr() catch |e| switch (e) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.FatalError => return error.FatalError,
+ error.ParsingFailed => return false,
+ };
+ if (res.val.tag == .unavailable) {
+ try p.errTok(.expected_expr, p.tok_i);
+ return false;
+ }
+ return res.val.getBool();
+}
+
+const CallExpr = union(enum) {
+ standard: NodeIndex,
+ builtin: struct {
+ node: NodeIndex,
+ tag: BuiltinFunction.Tag,
+ },
+
+ fn init(p: *Parser, call_node: NodeIndex, func_node: NodeIndex) CallExpr {
+ if (p.getNode(call_node, .builtin_call_expr_one)) |node| {
+ const data = p.nodes.items(.data)[@intFromEnum(node)];
+ const name = p.tokSlice(data.decl.name);
+ const builtin_ty = p.comp.builtins.lookup(name);
+ return .{ .builtin = .{ .node = node, .tag = builtin_ty.builtin.tag } };
+ }
+ return .{ .standard = func_node };
+ }
+
+ fn shouldPerformLvalConversion(self: CallExpr, arg_idx: u32) bool {
+ return switch (self) {
+ .standard => true,
+ .builtin => |builtin| switch (builtin.tag) {
+ .__builtin_va_start, .__va_start, .va_start => arg_idx != 1,
+ else => true,
+ },
+ };
+ }
+
+ fn shouldPromoteVarArg(self: CallExpr, arg_idx: u32) bool {
+ return switch (self) {
+ .standard => true,
+ .builtin => |builtin| switch (builtin.tag) {
+ .__builtin_va_start, .__va_start, .va_start => arg_idx != 1,
+ .__builtin_complex => false,
+ else => true,
+ },
+ };
+ }
+
+ fn shouldCoerceArg(self: CallExpr, arg_idx: u32) bool {
+ _ = self;
+ _ = arg_idx;
+ return true;
+ }
+
+ fn checkVarArg(self: CallExpr, p: *Parser, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32) !void {
+ if (self == .standard) return;
+
+ const builtin_tok = p.nodes.items(.data)[@intFromEnum(self.builtin.node)].decl.name;
+ switch (self.builtin.tag) {
+ .__builtin_va_start, .__va_start, .va_start => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx),
+ .__builtin_complex => return p.checkComplexArg(builtin_tok, first_after, param_tok, arg, arg_idx),
+ else => {},
+ }
+ }
+
+ /// Some functions cannot be expressed as standard C prototypes. For example `__builtin_complex` requires
+ /// two arguments of the same real floating point type (e.g. two doubles or two floats). These functions are
+ /// encoded as varargs functions with custom typechecking. Since varargs functions do not have a fixed number
+ /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for
+ /// these custom-typechecked functions.
+ fn paramCountOverride(self: CallExpr) ?u32 {
+ return switch (self) {
+ .standard => null,
+ .builtin => |builtin| switch (builtin.tag) {
+ .__builtin_complex => 2,
+ else => null,
+ },
+ };
+ }
+
+ fn returnType(self: CallExpr, p: *Parser, callable_ty: Type) Type {
+ return switch (self) {
+ .standard => callable_ty.returnType(),
+ .builtin => |builtin| switch (builtin.tag) {
+ .__builtin_complex => {
+ const last_param = p.list_buf.items[p.list_buf.items.len - 1];
+ return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex();
+ },
+ else => callable_ty.returnType(),
+ },
+ };
+ }
+
+ fn finish(self: CallExpr, p: *Parser, ty: Type, list_buf_top: usize, arg_count: u32) Error!Result {
+ const ret_ty = self.returnType(p, ty);
+ switch (self) {
+ .standard => |func_node| {
+ var call_node: Tree.Node = .{
+ .tag = .call_expr_one,
+ .ty = ret_ty,
+ .data = .{ .bin = .{ .lhs = func_node, .rhs = .none } },
+ };
+ const args = p.list_buf.items[list_buf_top..];
+ switch (arg_count) {
+ 0 => {},
+ 1 => call_node.data.bin.rhs = args[1], // args[0] == func.node
+ else => {
+ call_node.tag = .call_expr;
+ call_node.data = .{ .range = try p.addList(args) };
+ },
+ }
+ return Result{ .node = try p.addNode(call_node), .ty = ret_ty };
+ },
+ .builtin => |builtin| {
+ const index = @intFromEnum(builtin.node);
+ var call_node = p.nodes.get(index);
+ defer p.nodes.set(index, call_node);
+ call_node.ty = ret_ty;
+ const args = p.list_buf.items[list_buf_top..];
+ switch (arg_count) {
+ 0 => {},
+ 1 => call_node.data.decl.node = args[1], // args[0] == func.node
+ else => {
+ call_node.tag = .builtin_call_expr;
+ args[0] = @enumFromInt(call_node.data.decl.name);
+ call_node.data = .{ .range = try p.addList(args) };
+ },
+ }
+ return Result{ .node = builtin.node, .ty = ret_ty };
+ },
+ }
+ }
+};
+
+const Result = struct {
+ node: NodeIndex = .none,
+ ty: Type = .{ .specifier = .int },
+ val: Value = .{},
+
+ fn expect(res: Result, p: *Parser) Error!void {
+ if (p.in_macro) {
+ if (res.val.tag == .unavailable) {
+ try p.errTok(.expected_expr, p.tok_i);
+ return error.ParsingFailed;
+ }
+ return;
+ }
+ if (res.node == .none) {
+ try p.errTok(.expected_expr, p.tok_i);
+ return error.ParsingFailed;
+ }
+ }
+
+ fn empty(res: Result, p: *Parser) bool {
+ if (p.in_macro) return res.val.tag == .unavailable;
+ return res.node == .none;
+ }
+
+ fn maybeWarnUnused(res: Result, p: *Parser, expr_start: TokenIndex, err_start: usize) Error!void {
+ if (res.ty.is(.void) or res.node == .none) return;
+ // don't warn about unused result if the expression contained errors besides other unused results
+ for (p.comp.diag.list.items[err_start..]) |err_item| {
+ if (err_item.tag != .unused_value) return;
+ }
+ var cur_node = res.node;
+ while (true) switch (p.nodes.items(.tag)[@intFromEnum(cur_node)]) {
+ .invalid, // So that we don't need to check for node == 0
+ .assign_expr,
+ .mul_assign_expr,
+ .div_assign_expr,
+ .mod_assign_expr,
+ .add_assign_expr,
+ .sub_assign_expr,
+ .shl_assign_expr,
+ .shr_assign_expr,
+ .bit_and_assign_expr,
+ .bit_xor_assign_expr,
+ .bit_or_assign_expr,
+ .pre_inc_expr,
+ .pre_dec_expr,
+ .post_inc_expr,
+ .post_dec_expr,
+ => return,
+ .call_expr_one => {
+ const fn_ptr = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.lhs;
+ const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
+ if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
+ if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
+ return;
+ },
+ .call_expr => {
+ const fn_ptr = p.data.items[p.nodes.items(.data)[@intFromEnum(cur_node)].range.start];
+ const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
+ if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
+ if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
+ return;
+ },
+ .stmt_expr => {
+ const body = p.nodes.items(.data)[@intFromEnum(cur_node)].un;
+ switch (p.nodes.items(.tag)[@intFromEnum(body)]) {
+ .compound_stmt_two => {
+ const body_stmt = p.nodes.items(.data)[@intFromEnum(body)].bin;
+ cur_node = if (body_stmt.rhs != .none) body_stmt.rhs else body_stmt.lhs;
+ },
+ .compound_stmt => {
+ const data = p.nodes.items(.data)[@intFromEnum(body)];
+ cur_node = p.data.items[data.range.end - 1];
+ },
+ else => unreachable,
+ }
+ },
+ .comma_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.rhs,
+ .paren_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].un,
+ else => break,
+ };
+ try p.errTok(.unused_value, expr_start);
+ }
+
+ fn boolRes(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
+ if (lhs.val.tag == .nullptr_t) {
+ lhs.val = Value.int(0);
+ }
+ if (lhs.ty.specifier != .invalid) {
+ lhs.ty = Type.int;
+ }
+ return lhs.bin(p, tag, rhs);
+ }
+
+ fn bin(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
+ lhs.node = try p.addNode(.{
+ .tag = tag,
+ .ty = lhs.ty,
+ .data = .{ .bin = .{ .lhs = lhs.node, .rhs = rhs.node } },
+ });
+ }
+
+ fn un(operand: *Result, p: *Parser, tag: Tree.Tag) Error!void {
+ operand.node = try p.addNode(.{
+ .tag = tag,
+ .ty = operand.ty,
+ .data = .{ .un = operand.node },
+ });
+ }
+
+ fn implicitCast(operand: *Result, p: *Parser, kind: Tree.CastKind) Error!void {
+ operand.node = try p.addNode(.{
+ .tag = .implicit_cast,
+ .ty = operand.ty,
+ .data = .{ .cast = .{ .operand = operand.node, .kind = kind } },
+ });
+ }
+
+ fn adjustCondExprPtrs(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) !bool {
+ assert(a.ty.isPtr() and b.ty.isPtr());
+
+ const a_elem = a.ty.elemType();
+ const b_elem = b.ty.elemType();
+ if (a_elem.eql(b_elem, p.comp, true)) return true;
+
+ var adjusted_elem_ty = try p.arena.create(Type);
+ adjusted_elem_ty.* = a_elem;
+
+ const has_void_star_branch = a.ty.isVoidStar() or b.ty.isVoidStar();
+ const only_quals_differ = a_elem.eql(b_elem, p.comp, false);
+ const pointers_compatible = only_quals_differ or has_void_star_branch;
+
+ if (!pointers_compatible or has_void_star_branch) {
+ if (!pointers_compatible) {
+ try p.errStr(.pointer_mismatch, tok, try p.typePairStrExtra(a.ty, " and ", b.ty));
+ }
+ adjusted_elem_ty.* = .{ .specifier = .void };
+ }
+ if (pointers_compatible) {
+ adjusted_elem_ty.qual = a_elem.qual.mergeCV(b_elem.qual);
+ }
+ if (!adjusted_elem_ty.eql(a_elem, p.comp, true)) {
+ a.ty = .{
+ .data = .{ .sub_type = adjusted_elem_ty },
+ .specifier = .pointer,
+ };
+ try a.implicitCast(p, .bitcast);
+ }
+ if (!adjusted_elem_ty.eql(b_elem, p.comp, true)) {
+ b.ty = .{
+ .data = .{ .sub_type = adjusted_elem_ty },
+ .specifier = .pointer,
+ };
+ try b.implicitCast(p, .bitcast);
+ }
+ return true;
+ }
+
+ /// Adjust types for binary operation, returns true if the result can and should be evaluated.
+ fn adjustTypes(a: *Result, tok: TokenIndex, b: *Result, p: *Parser, kind: enum {
+ integer,
+ arithmetic,
+ boolean_logic,
+ relational,
+ equality,
+ conditional,
+ add,
+ sub,
+ }) !bool {
+ if (b.ty.specifier == .invalid) {
+ try a.saveValue(p);
+ a.ty = Type.invalid;
+ }
+ if (a.ty.specifier == .invalid) {
+ return false;
+ }
+ try a.lvalConversion(p);
+ try b.lvalConversion(p);
+
+ const a_vec = a.ty.is(.vector);
+ const b_vec = b.ty.is(.vector);
+ if (a_vec and b_vec) {
+ if (a.ty.eql(b.ty, p.comp, false)) {
+ return a.shouldEval(b, p);
+ }
+ return a.invalidBinTy(tok, b, p);
+ } else if (a_vec) {
+ if (b.coerceExtra(p, a.ty.elemType(), tok, .test_coerce)) {
+ try b.saveValue(p);
+ try b.implicitCast(p, .vector_splat);
+ return a.shouldEval(b, p);
+ } else |er| switch (er) {
+ error.CoercionFailed => return a.invalidBinTy(tok, b, p),
+ else => |e| return e,
+ }
+ } else if (b_vec) {
+ if (a.coerceExtra(p, b.ty.elemType(), tok, .test_coerce)) {
+ try a.saveValue(p);
+ try a.implicitCast(p, .vector_splat);
+ return a.shouldEval(b, p);
+ } else |er| switch (er) {
+ error.CoercionFailed => return a.invalidBinTy(tok, b, p),
+ else => |e| return e,
+ }
+ }
+
+ const a_int = a.ty.isInt();
+ const b_int = b.ty.isInt();
+ if (a_int and b_int) {
+ try a.usualArithmeticConversion(b, p, tok);
+ return a.shouldEval(b, p);
+ }
+ if (kind == .integer) return a.invalidBinTy(tok, b, p);
+
+ const a_float = a.ty.isFloat();
+ const b_float = b.ty.isFloat();
+ const a_arithmetic = a_int or a_float;
+ const b_arithmetic = b_int or b_float;
+ if (a_arithmetic and b_arithmetic) {
+ // <, <=, >, >= only work on real types
+ if (kind == .relational and (!a.ty.isReal() or !b.ty.isReal()))
+ return a.invalidBinTy(tok, b, p);
+
+ try a.usualArithmeticConversion(b, p, tok);
+ return a.shouldEval(b, p);
+ }
+ if (kind == .arithmetic) return a.invalidBinTy(tok, b, p);
+
+ const a_nullptr = a.ty.is(.nullptr_t);
+ const b_nullptr = b.ty.is(.nullptr_t);
+ const a_ptr = a.ty.isPtr();
+ const b_ptr = b.ty.isPtr();
+ const a_scalar = a_arithmetic or a_ptr;
+ const b_scalar = b_arithmetic or b_ptr;
+ switch (kind) {
+ .boolean_logic => {
+ if (!(a_scalar or a_nullptr) or !(b_scalar or b_nullptr)) return a.invalidBinTy(tok, b, p);
+
+ // Do integer promotions but nothing else
+ if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
+ if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
+ return a.shouldEval(b, p);
+ },
+ .relational, .equality => {
+ if (kind == .equality and (a_nullptr or b_nullptr)) {
+ if (a_nullptr and b_nullptr) return a.shouldEval(b, p);
+ const nullptr_res = if (a_nullptr) a else b;
+ const other_res = if (a_nullptr) b else a;
+ if (other_res.ty.isPtr()) {
+ try nullptr_res.nullCast(p, other_res.ty);
+ return other_res.shouldEval(nullptr_res, p);
+ } else if (other_res.val.isZero()) {
+ other_res.val = .{ .tag = .nullptr_t };
+ try other_res.nullCast(p, nullptr_res.ty);
+ return other_res.shouldEval(nullptr_res, p);
+ }
+ return a.invalidBinTy(tok, b, p);
+ }
+ // comparisons between floats and pointes not allowed
+ if (!a_scalar or !b_scalar or (a_float and b_ptr) or (b_float and a_ptr))
+ return a.invalidBinTy(tok, b, p);
+
+ if ((a_int or b_int) and !(a.val.isZero() or b.val.isZero())) {
+ try p.errStr(.comparison_ptr_int, tok, try p.typePairStr(a.ty, b.ty));
+ } else if (a_ptr and b_ptr) {
+ if (!a.ty.isVoidStar() and !b.ty.isVoidStar() and !a.ty.eql(b.ty, p.comp, false))
+ try p.errStr(.comparison_distinct_ptr, tok, try p.typePairStr(a.ty, b.ty));
+ } else if (a_ptr) {
+ try b.ptrCast(p, a.ty);
+ } else {
+ assert(b_ptr);
+ try a.ptrCast(p, b.ty);
+ }
+
+ return a.shouldEval(b, p);
+ },
+ .conditional => {
+ // doesn't matter what we return here, as the result is ignored
+ if (a.ty.is(.void) or b.ty.is(.void)) {
+ try a.toVoid(p);
+ try b.toVoid(p);
+ return true;
+ }
+ if (a_nullptr and b_nullptr) return true;
+ if ((a_ptr and b_int) or (a_int and b_ptr)) {
+ if (a.val.isZero() or b.val.isZero()) {
+ try a.nullCast(p, b.ty);
+ try b.nullCast(p, a.ty);
+ return true;
+ }
+ const int_ty = if (a_int) a else b;
+ const ptr_ty = if (a_ptr) a else b;
+ try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(int_ty.ty, " to ", ptr_ty.ty));
+ try int_ty.ptrCast(p, ptr_ty.ty);
+
+ return true;
+ }
+ if (a_ptr and b_ptr) return a.adjustCondExprPtrs(tok, b, p);
+ if ((a_ptr and b_nullptr) or (a_nullptr and b_ptr)) {
+ const nullptr_res = if (a_nullptr) a else b;
+ const ptr_res = if (a_nullptr) b else a;
+ try nullptr_res.nullCast(p, ptr_res.ty);
+ return true;
+ }
+ if (a.ty.isRecord() and b.ty.isRecord() and a.ty.eql(b.ty, p.comp, false)) {
+ return true;
+ }
+ return a.invalidBinTy(tok, b, p);
+ },
+ .add => {
+ // if both aren't arithmetic one should be pointer and the other an integer
+ if (a_ptr == b_ptr or a_int == b_int) return a.invalidBinTy(tok, b, p);
+
+ // Do integer promotions but nothing else
+ if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
+ if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
+
+ // The result type is the type of the pointer operand
+ if (a_int) a.ty = b.ty else b.ty = a.ty;
+ return a.shouldEval(b, p);
+ },
+ .sub => {
+ // if both aren't arithmetic then either both should be pointers or just a
+ if (!a_ptr or !(b_ptr or b_int)) return a.invalidBinTy(tok, b, p);
+
+ if (a_ptr and b_ptr) {
+ if (!a.ty.eql(b.ty, p.comp, false)) try p.errStr(.incompatible_pointers, tok, try p.typePairStr(a.ty, b.ty));
+ a.ty = p.comp.types.ptrdiff;
+ }
+
+ // Do integer promotion on b if needed
+ if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
+ return a.shouldEval(b, p);
+ },
+ else => return a.invalidBinTy(tok, b, p),
+ }
+ }
+
+ fn lvalConversion(res: *Result, p: *Parser) Error!void {
+ if (res.ty.isFunc()) {
+ var elem_ty = try p.arena.create(Type);
+ elem_ty.* = res.ty;
+ res.ty.specifier = .pointer;
+ res.ty.data = .{ .sub_type = elem_ty };
+ try res.implicitCast(p, .function_to_pointer);
+ } else if (res.ty.isArray()) {
+ res.val.tag = .unavailable;
+ res.ty.decayArray();
+ try res.implicitCast(p, .array_to_pointer);
+ } else if (!p.in_macro and Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, res.node)) {
+ res.ty.qual = .{};
+ try res.implicitCast(p, .lval_to_rval);
+ }
+ }
+
+ fn boolCast(res: *Result, p: *Parser, bool_ty: Type, tok: TokenIndex) Error!void {
+ if (res.ty.isArray()) {
+ if (res.val.tag == .bytes) {
+ try p.errStr(.string_literal_to_bool, tok, try p.typePairStrExtra(res.ty, " to ", bool_ty));
+ } else {
+ try p.errStr(.array_address_to_bool, tok, p.tokSlice(tok));
+ }
+ try res.lvalConversion(p);
+ res.val = Value.int(1);
+ res.ty = bool_ty;
+ try res.implicitCast(p, .pointer_to_bool);
+ } else if (res.ty.isPtr()) {
+ res.val.toBool();
+ res.ty = bool_ty;
+ try res.implicitCast(p, .pointer_to_bool);
+ } else if (res.ty.isInt() and !res.ty.is(.bool)) {
+ res.val.toBool();
+ res.ty = bool_ty;
+ try res.implicitCast(p, .int_to_bool);
+ } else if (res.ty.isFloat()) {
+ const old_value = res.val;
+ const value_change_kind = res.val.floatToInt(res.ty, bool_ty, p.comp);
+ try res.floatToIntWarning(p, bool_ty, old_value, value_change_kind, tok);
+ if (!res.ty.isReal()) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_float_to_real);
+ }
+ res.ty = bool_ty;
+ try res.implicitCast(p, .float_to_bool);
+ }
+ }
+
+ fn intCast(res: *Result, p: *Parser, int_ty: Type, tok: TokenIndex) Error!void {
+ if (int_ty.hasIncompleteSize()) return error.ParsingFailed; // Diagnostic already issued
+ if (res.ty.is(.bool)) {
+ res.ty = int_ty.makeReal();
+ try res.implicitCast(p, .bool_to_int);
+ if (!int_ty.isReal()) {
+ res.ty = int_ty;
+ try res.implicitCast(p, .real_to_complex_int);
+ }
+ } else if (res.ty.isPtr()) {
+ res.ty = int_ty.makeReal();
+ try res.implicitCast(p, .pointer_to_int);
+ if (!int_ty.isReal()) {
+ res.ty = int_ty;
+ try res.implicitCast(p, .real_to_complex_int);
+ }
+ } else if (res.ty.isFloat()) {
+ const old_value = res.val;
+ const value_change_kind = res.val.floatToInt(res.ty, int_ty, p.comp);
+ try res.floatToIntWarning(p, int_ty, old_value, value_change_kind, tok);
+ const old_real = res.ty.isReal();
+ const new_real = int_ty.isReal();
+ if (old_real and new_real) {
+ res.ty = int_ty;
+ try res.implicitCast(p, .float_to_int);
+ } else if (old_real) {
+ res.ty = int_ty.makeReal();
+ try res.implicitCast(p, .float_to_int);
+ res.ty = int_ty;
+ try res.implicitCast(p, .real_to_complex_int);
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_float_to_real);
+ res.ty = int_ty;
+ try res.implicitCast(p, .float_to_int);
+ } else {
+ res.ty = int_ty;
+ try res.implicitCast(p, .complex_float_to_complex_int);
+ }
+ } else if (!res.ty.eql(int_ty, p.comp, true)) {
+ res.val.intCast(res.ty, int_ty, p.comp);
+ const old_real = res.ty.isReal();
+ const new_real = int_ty.isReal();
+ if (old_real and new_real) {
+ res.ty = int_ty;
+ try res.implicitCast(p, .int_cast);
+ } else if (old_real) {
+ const real_int_ty = int_ty.makeReal();
+ if (!res.ty.eql(real_int_ty, p.comp, false)) {
+ res.ty = real_int_ty;
+ try res.implicitCast(p, .int_cast);
+ }
+ res.ty = int_ty;
+ try res.implicitCast(p, .real_to_complex_int);
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_int_to_real);
+ res.ty = int_ty;
+ try res.implicitCast(p, .int_cast);
+ } else {
+ res.ty = int_ty;
+ try res.implicitCast(p, .complex_int_cast);
+ }
+ }
+ }
+
+ fn floatToIntWarning(res: *Result, p: *Parser, int_ty: Type, old_value: Value, change_kind: Value.FloatToIntChangeKind, tok: TokenIndex) !void {
+ switch (change_kind) {
+ .none => return p.errStr(.float_to_int, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
+ .out_of_range => return p.errStr(.float_out_of_range, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
+ .overflow => return p.errStr(.float_overflow_conversion, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
+ .nonzero_to_zero => return p.errStr(.float_zero_conversion, tok, try p.floatValueChangedStr(res, old_value.getFloat(f64), int_ty)),
+ .value_changed => return p.errStr(.float_value_changed, tok, try p.floatValueChangedStr(res, old_value.getFloat(f64), int_ty)),
+ }
+ }
+
+ fn floatCast(res: *Result, p: *Parser, float_ty: Type) Error!void {
+ if (res.ty.is(.bool)) {
+ res.val.intToFloat(res.ty, float_ty, p.comp);
+ res.ty = float_ty.makeReal();
+ try res.implicitCast(p, .bool_to_float);
+ if (!float_ty.isReal()) {
+ res.ty = float_ty;
+ try res.implicitCast(p, .real_to_complex_float);
+ }
+ } else if (res.ty.isInt()) {
+ res.val.intToFloat(res.ty, float_ty, p.comp);
+ const old_real = res.ty.isReal();
+ const new_real = float_ty.isReal();
+ if (old_real and new_real) {
+ res.ty = float_ty;
+ try res.implicitCast(p, .int_to_float);
+ } else if (old_real) {
+ res.ty = float_ty.makeReal();
+ try res.implicitCast(p, .int_to_float);
+ res.ty = float_ty;
+ try res.implicitCast(p, .real_to_complex_float);
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_int_to_real);
+ res.ty = float_ty;
+ try res.implicitCast(p, .int_to_float);
+ } else {
+ res.ty = float_ty;
+ try res.implicitCast(p, .complex_int_to_complex_float);
+ }
+ } else if (!res.ty.eql(float_ty, p.comp, true)) {
+ res.val.floatCast(res.ty, float_ty, p.comp);
+ const old_real = res.ty.isReal();
+ const new_real = float_ty.isReal();
+ if (old_real and new_real) {
+ res.ty = float_ty;
+ try res.implicitCast(p, .float_cast);
+ } else if (old_real) {
+ if (res.ty.floatRank() != float_ty.floatRank()) {
+ res.ty = float_ty.makeReal();
+ try res.implicitCast(p, .float_cast);
+ }
+ res.ty = float_ty;
+ try res.implicitCast(p, .real_to_complex_float);
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_float_to_real);
+ if (res.ty.floatRank() != float_ty.floatRank()) {
+ res.ty = float_ty;
+ try res.implicitCast(p, .float_cast);
+ }
+ } else {
+ res.ty = float_ty;
+ try res.implicitCast(p, .complex_float_cast);
+ }
+ }
+ }
+
+ /// Converts a bool or integer to a pointer
+ fn ptrCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
+ if (res.ty.is(.bool)) {
+ res.ty = ptr_ty;
+ try res.implicitCast(p, .bool_to_pointer);
+ } else if (res.ty.isInt()) {
+ res.val.intCast(res.ty, ptr_ty, p.comp);
+ res.ty = ptr_ty;
+ try res.implicitCast(p, .int_to_pointer);
+ }
+ }
+
+ /// Convert pointer to one with a different child type
+ fn ptrChildTypeCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
+ res.ty = ptr_ty;
+ return res.implicitCast(p, .bitcast);
+ }
+
+ fn toVoid(res: *Result, p: *Parser) Error!void {
+ if (!res.ty.is(.void)) {
+ res.ty = .{ .specifier = .void };
+ try res.implicitCast(p, .to_void);
+ }
+ }
+
+ fn nullCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
+ if (!res.ty.is(.nullptr_t) and !res.val.isZero()) return;
+ res.ty = ptr_ty;
+ try res.implicitCast(p, .null_to_pointer);
+ }
+
+ fn usualUnaryConversion(res: *Result, p: *Parser, tok: TokenIndex) Error!void {
+ if (res.ty.isFloat()) fp_eval: {
+ const eval_method = p.comp.langopts.fp_eval_method orelse break :fp_eval;
+ switch (eval_method) {
+ .source => {},
+ .indeterminate => unreachable,
+ .double => {
+ if (res.ty.floatRank() < (Type{ .specifier = .double }).floatRank()) {
+ const spec: Type.Specifier = if (res.ty.isReal()) .double else .complex_double;
+ return res.floatCast(p, .{ .specifier = spec });
+ }
+ },
+ .extended => {
+ if (res.ty.floatRank() < (Type{ .specifier = .long_double }).floatRank()) {
+ const spec: Type.Specifier = if (res.ty.isReal()) .long_double else .complex_long_double;
+ return res.floatCast(p, .{ .specifier = spec });
+ }
+ },
+ }
+ }
+
+ if (res.ty.is(.fp16) and !p.comp.langopts.use_native_half_type) {
+ return res.floatCast(p, .{ .specifier = .float });
+ }
+ if (res.ty.isInt()) {
+ const slice = p.nodes.slice();
+ if (Tree.bitfieldWidth(slice, res.node, true)) |width| {
+ if (res.ty.bitfieldPromotion(p.comp, width)) |promotion_ty| {
+ return res.intCast(p, promotion_ty, tok);
+ }
+ }
+ return res.intCast(p, res.ty.integerPromotion(p.comp), tok);
+ }
+ }
+
+ fn usualArithmeticConversion(a: *Result, b: *Result, p: *Parser, tok: TokenIndex) Error!void {
+ try a.usualUnaryConversion(p, tok);
+ try b.usualUnaryConversion(p, tok);
+
+ // if either is a float cast to that type
+ if (a.ty.isFloat() or b.ty.isFloat()) {
+ const float_types = [7][2]Type.Specifier{
+ .{ .complex_long_double, .long_double },
+ .{ .complex_float128, .float128 },
+ .{ .complex_float80, .float80 },
+ .{ .complex_double, .double },
+ .{ .complex_float, .float },
+ // No `_Complex __fp16` type
+ .{ .invalid, .fp16 },
+ // No `_Complex _Float16`
+ .{ .invalid, .float16 },
+ };
+ const a_spec = a.ty.canonicalize(.standard).specifier;
+ const b_spec = b.ty.canonicalize(.standard).specifier;
+ if (p.comp.target.c_type_bit_size(.longdouble) == 128) {
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
+ }
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[1])) return;
+ if (p.comp.target.c_type_bit_size(.longdouble) == 80) {
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
+ }
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[2])) return;
+ if (p.comp.target.c_type_bit_size(.longdouble) == 64) {
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
+ }
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[3])) return;
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[4])) return;
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[5])) return;
+ if (try a.floatConversion(b, a_spec, b_spec, p, float_types[6])) return;
+ }
+
+ if (a.ty.eql(b.ty, p.comp, true)) {
+ // cast to promoted type
+ try a.intCast(p, a.ty, tok);
+ try b.intCast(p, b.ty, tok);
+ return;
+ }
+
+ const target = a.ty.integerConversion(b.ty, p.comp);
+ if (!target.isReal()) {
+ try a.saveValue(p);
+ try b.saveValue(p);
+ }
+ try a.intCast(p, target, tok);
+ try b.intCast(p, target, tok);
+ }
+
+ fn floatConversion(a: *Result, b: *Result, a_spec: Type.Specifier, b_spec: Type.Specifier, p: *Parser, pair: [2]Type.Specifier) !bool {
+ if (a_spec == pair[0] or a_spec == pair[1] or
+ b_spec == pair[0] or b_spec == pair[1])
+ {
+ const both_real = a.ty.isReal() and b.ty.isReal();
+ const res_spec = pair[@intFromBool(both_real)];
+ const ty = Type{ .specifier = res_spec };
+ try a.floatCast(p, ty);
+ try b.floatCast(p, ty);
+ return true;
+ }
+ return false;
+ }
+
+ fn invalidBinTy(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) Error!bool {
+ try p.errStr(.invalid_bin_types, tok, try p.typePairStr(a.ty, b.ty));
+ a.val.tag = .unavailable;
+ b.val.tag = .unavailable;
+ a.ty = Type.invalid;
+ return false;
+ }
+
+ fn shouldEval(a: *Result, b: *Result, p: *Parser) Error!bool {
+ if (p.no_eval) return false;
+ if (a.val.tag != .unavailable and b.val.tag != .unavailable)
+ return true;
+
+ try a.saveValue(p);
+ try b.saveValue(p);
+ return p.no_eval;
+ }
+
+ /// Saves value and replaces it with `.unavailable`.
+ fn saveValue(res: *Result, p: *Parser) !void {
+ assert(!p.in_macro);
+ if (res.val.tag == .unavailable or res.val.tag == .nullptr_t) return;
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ res.val.tag = .unavailable;
+ }
+
+ fn castType(res: *Result, p: *Parser, to: Type, tok: TokenIndex) !void {
+ var cast_kind: Tree.CastKind = undefined;
+
+ if (to.is(.void)) {
+ // everything can cast to void
+ cast_kind = .to_void;
+ res.val.tag = .unavailable;
+ } else if (to.is(.nullptr_t)) {
+ if (res.ty.is(.nullptr_t)) {
+ cast_kind = .no_op;
+ } else {
+ try p.errStr(.invalid_object_cast, tok, try p.typePairStrExtra(res.ty, " to ", to));
+ return error.ParsingFailed;
+ }
+ } else if (res.ty.is(.nullptr_t)) {
+ if (to.is(.bool)) {
+ try res.nullCast(p, res.ty);
+ res.val.toBool();
+ res.ty = .{ .specifier = .bool };
+ try res.implicitCast(p, .pointer_to_bool);
+ try res.saveValue(p);
+ } else if (to.isPtr()) {
+ try res.nullCast(p, to);
+ } else {
+ try p.errStr(.invalid_object_cast, tok, try p.typePairStrExtra(res.ty, " to ", to));
+ return error.ParsingFailed;
+ }
+ cast_kind = .no_op;
+ } else if (res.val.isZero() and to.isPtr()) {
+ cast_kind = .null_to_pointer;
+ } else if (to.isScalar()) cast: {
+ const old_float = res.ty.isFloat();
+ const new_float = to.isFloat();
+
+ if (new_float and res.ty.isPtr()) {
+ try p.errStr(.invalid_cast_to_float, tok, try p.typeStr(to));
+ return error.ParsingFailed;
+ } else if (old_float and to.isPtr()) {
+ try p.errStr(.invalid_cast_to_pointer, tok, try p.typeStr(res.ty));
+ return error.ParsingFailed;
+ }
+ const old_real = res.ty.isReal();
+ const new_real = to.isReal();
+
+ if (to.eql(res.ty, p.comp, false)) {
+ cast_kind = .no_op;
+ } else if (to.is(.bool)) {
+ if (res.ty.isPtr()) {
+ cast_kind = .pointer_to_bool;
+ } else if (res.ty.isInt()) {
+ if (!old_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_int_to_real);
+ }
+ cast_kind = .int_to_bool;
+ } else if (old_float) {
+ if (!old_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_float_to_real);
+ }
+ cast_kind = .float_to_bool;
+ }
+ } else if (to.isInt()) {
+ if (res.ty.is(.bool)) {
+ if (!new_real) {
+ res.ty = to.makeReal();
+ try res.implicitCast(p, .bool_to_int);
+ cast_kind = .real_to_complex_int;
+ } else {
+ cast_kind = .bool_to_int;
+ }
+ } else if (res.ty.isInt()) {
+ if (old_real and new_real) {
+ cast_kind = .int_cast;
+ } else if (old_real) {
+ res.ty = to.makeReal();
+ try res.implicitCast(p, .int_cast);
+ cast_kind = .real_to_complex_int;
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_int_to_real);
+ cast_kind = .int_cast;
+ } else {
+ cast_kind = .complex_int_cast;
+ }
+ } else if (res.ty.isPtr()) {
+ if (!new_real) {
+ res.ty = to.makeReal();
+ try res.implicitCast(p, .pointer_to_int);
+ cast_kind = .real_to_complex_int;
+ } else {
+ cast_kind = .pointer_to_int;
+ }
+ } else if (old_real and new_real) {
+ cast_kind = .float_to_int;
+ } else if (old_real) {
+ res.ty = to.makeReal();
+ try res.implicitCast(p, .float_to_int);
+ cast_kind = .real_to_complex_int;
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_float_to_real);
+ cast_kind = .float_to_int;
+ } else {
+ cast_kind = .complex_float_to_complex_int;
+ }
+ } else if (to.isPtr()) {
+ if (res.ty.isArray())
+ cast_kind = .array_to_pointer
+ else if (res.ty.isPtr())
+ cast_kind = .bitcast
+ else if (res.ty.isFunc())
+ cast_kind = .function_to_pointer
+ else if (res.ty.is(.bool))
+ cast_kind = .bool_to_pointer
+ else if (res.ty.isInt()) {
+ if (!old_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_int_to_real);
+ }
+ cast_kind = .int_to_pointer;
+ }
+ } else if (new_float) {
+ if (res.ty.is(.bool)) {
+ if (!new_real) {
+ res.ty = to.makeReal();
+ try res.implicitCast(p, .bool_to_float);
+ cast_kind = .real_to_complex_float;
+ } else {
+ cast_kind = .bool_to_float;
+ }
+ } else if (res.ty.isInt()) {
+ if (old_real and new_real) {
+ cast_kind = .int_to_float;
+ } else if (old_real) {
+ res.ty = to.makeReal();
+ try res.implicitCast(p, .int_to_float);
+ cast_kind = .real_to_complex_float;
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_int_to_real);
+ cast_kind = .int_to_float;
+ } else {
+ cast_kind = .complex_int_to_complex_float;
+ }
+ } else if (old_real and new_real) {
+ cast_kind = .float_cast;
+ } else if (old_real) {
+ res.ty = to.makeReal();
+ try res.implicitCast(p, .float_cast);
+ cast_kind = .real_to_complex_float;
+ } else if (new_real) {
+ res.ty = res.ty.makeReal();
+ try res.implicitCast(p, .complex_float_to_real);
+ cast_kind = .float_cast;
+ } else {
+ cast_kind = .complex_float_cast;
+ }
+ }
+ if (res.val.tag == .unavailable) break :cast;
+
+ const old_int = res.ty.isInt() or res.ty.isPtr();
+ const new_int = to.isInt() or to.isPtr();
+ if (to.is(.bool)) {
+ res.val.toBool();
+ } else if (old_float and new_int) {
+ // Explicit cast, no conversion warning
+ _ = res.val.floatToInt(res.ty, to, p.comp);
+ } else if (new_float and old_int) {
+ res.val.intToFloat(res.ty, to, p.comp);
+ } else if (new_float and old_float) {
+ res.val.floatCast(res.ty, to, p.comp);
+ } else if (old_int and new_int) {
+ if (to.hasIncompleteSize()) {
+ try p.errStr(.cast_to_incomplete_type, tok, try p.typeStr(to));
+ return error.ParsingFailed;
+ }
+ res.val.intCast(res.ty, to, p.comp);
+ }
+ } else if (to.get(.@"union")) |union_ty| {
+ if (union_ty.data.record.hasFieldOfType(res.ty, p.comp)) {
+ cast_kind = .union_cast;
+ try p.errTok(.gnu_union_cast, tok);
+ } else {
+ if (union_ty.data.record.isIncomplete()) {
+ try p.errStr(.cast_to_incomplete_type, tok, try p.typeStr(to));
+ } else {
+ try p.errStr(.invalid_union_cast, tok, try p.typeStr(res.ty));
+ }
+ return error.ParsingFailed;
+ }
+ } else {
+ if (to.is(.auto_type)) {
+ try p.errTok(.invalid_cast_to_auto_type, tok);
+ } else {
+ try p.errStr(.invalid_cast_type, tok, try p.typeStr(to));
+ }
+ return error.ParsingFailed;
+ }
+ if (to.anyQual()) try p.errStr(.qual_cast, tok, try p.typeStr(to));
+ if (to.isInt() and res.ty.isPtr() and to.sizeCompare(res.ty, p.comp) == .lt) {
+ try p.errStr(.cast_to_smaller_int, tok, try p.typePairStrExtra(to, " from ", res.ty));
+ }
+ res.ty = to;
+ res.ty.qual = .{};
+ res.node = try p.addNode(.{
+ .tag = .explicit_cast,
+ .ty = res.ty,
+ .data = .{ .cast = .{ .operand = res.node, .kind = cast_kind } },
+ });
+ }
+
+ fn intFitsInType(res: Result, p: *Parser, ty: Type) bool {
+ const max_int = Value.int(ty.maxInt(p.comp));
+ const min_int = Value.int(ty.minInt(p.comp));
+ return res.val.compare(.lte, max_int, res.ty, p.comp) and
+ (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, min_int, res.ty, p.comp));
+ }
+
+ const CoerceContext = union(enum) {
+ assign,
+ init,
+ ret,
+ arg: TokenIndex,
+ test_coerce,
+
+ fn note(ctx: CoerceContext, p: *Parser) !void {
+ switch (ctx) {
+ .arg => |tok| try p.errTok(.parameter_here, tok),
+ .test_coerce => unreachable,
+ else => {},
+ }
+ }
+
+ fn typePairStr(ctx: CoerceContext, p: *Parser, dest_ty: Type, src_ty: Type) ![]const u8 {
+ switch (ctx) {
+ .assign, .init => return p.typePairStrExtra(dest_ty, " from incompatible type ", src_ty),
+ .ret => return p.typePairStrExtra(src_ty, " from a function with incompatible result type ", dest_ty),
+ .arg => return p.typePairStrExtra(src_ty, " to parameter of incompatible type ", dest_ty),
+ .test_coerce => unreachable,
+ }
+ }
+ };
+
+ /// Perform assignment-like coercion to `dest_ty`.
+ fn coerce(res: *Result, p: *Parser, dest_ty: Type, tok: TokenIndex, ctx: CoerceContext) Error!void {
+ if (res.ty.specifier == .invalid or dest_ty.specifier == .invalid) {
+ res.ty = Type.invalid;
+ return;
+ }
+ return res.coerceExtra(p, dest_ty, tok, ctx) catch |er| switch (er) {
+ error.CoercionFailed => unreachable,
+ else => |e| return e,
+ };
+ }
+
+ const Stage1Limitation = Error || error{CoercionFailed};
+ fn coerceExtra(res: *Result, p: *Parser, dest_ty: Type, tok: TokenIndex, ctx: CoerceContext) Stage1Limitation!void {
+ // Subject of the coercion does not need to be qualified.
+ var unqual_ty = dest_ty.canonicalize(.standard);
+ unqual_ty.qual = .{};
+ if (unqual_ty.is(.nullptr_t)) {
+ if (res.ty.is(.nullptr_t)) return;
+ } else if (unqual_ty.is(.bool)) {
+ if (res.ty.isScalar() and !res.ty.is(.nullptr_t)) {
+ // this is ridiculous but it's what clang does
+ try res.boolCast(p, unqual_ty, tok);
+ return;
+ }
+ } else if (unqual_ty.isInt()) {
+ if (res.ty.isInt() or res.ty.isFloat()) {
+ try res.intCast(p, unqual_ty, tok);
+ return;
+ } else if (res.ty.isPtr()) {
+ if (ctx == .test_coerce) return error.CoercionFailed;
+ try p.errStr(.implicit_ptr_to_int, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
+ try ctx.note(p);
+ try res.intCast(p, unqual_ty, tok);
+ return;
+ }
+ } else if (unqual_ty.isFloat()) {
+ if (res.ty.isInt() or res.ty.isFloat()) {
+ try res.floatCast(p, unqual_ty);
+ return;
+ }
+ } else if (unqual_ty.isPtr()) {
+ if (res.ty.is(.nullptr_t) or res.val.isZero()) {
+ try res.nullCast(p, dest_ty);
+ return;
+ } else if (res.ty.isInt() and res.ty.isReal()) {
+ if (ctx == .test_coerce) return error.CoercionFailed;
+ try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
+ try ctx.note(p);
+ try res.ptrCast(p, unqual_ty);
+ return;
+ } else if (res.ty.isVoidStar() or unqual_ty.eql(res.ty, p.comp, true)) {
+ return; // ok
+ } else if (unqual_ty.isVoidStar() and res.ty.isPtr() or (res.ty.isInt() and res.ty.isReal())) {
+ return; // ok
+ } else if (unqual_ty.eql(res.ty, p.comp, false)) {
+ if (!unqual_ty.elemType().qual.hasQuals(res.ty.elemType().qual)) {
+ try p.errStr(switch (ctx) {
+ .assign => .ptr_assign_discards_quals,
+ .init => .ptr_init_discards_quals,
+ .ret => .ptr_ret_discards_quals,
+ .arg => .ptr_arg_discards_quals,
+ .test_coerce => return error.CoercionFailed,
+ }, tok, try ctx.typePairStr(p, dest_ty, res.ty));
+ }
+ try res.ptrCast(p, unqual_ty);
+ return;
+ } else if (res.ty.isPtr()) {
+ const different_sign_only = unqual_ty.elemType().sameRankDifferentSign(res.ty.elemType(), p.comp);
+ try p.errStr(switch (ctx) {
+ .assign => ([2]Diagnostics.Tag{ .incompatible_ptr_assign, .incompatible_ptr_assign_sign })[@intFromBool(different_sign_only)],
+ .init => ([2]Diagnostics.Tag{ .incompatible_ptr_init, .incompatible_ptr_init_sign })[@intFromBool(different_sign_only)],
+ .ret => ([2]Diagnostics.Tag{ .incompatible_return, .incompatible_return_sign })[@intFromBool(different_sign_only)],
+ .arg => ([2]Diagnostics.Tag{ .incompatible_ptr_arg, .incompatible_ptr_arg_sign })[@intFromBool(different_sign_only)],
+ .test_coerce => return error.CoercionFailed,
+ }, tok, try ctx.typePairStr(p, dest_ty, res.ty));
+ try ctx.note(p);
+ try res.ptrChildTypeCast(p, unqual_ty);
+ return;
+ }
+ } else if (unqual_ty.isRecord()) {
+ if (unqual_ty.eql(res.ty, p.comp, false)) {
+ return; // ok
+ }
+
+ if (ctx == .arg) if (unqual_ty.get(.@"union")) |union_ty| {
+ if (dest_ty.hasAttribute(.transparent_union)) transparent_union: {
+ res.coerceExtra(p, union_ty.data.record.fields[0].ty, tok, .test_coerce) catch |er| switch (er) {
+ error.CoercionFailed => break :transparent_union,
+ else => |e| return e,
+ };
+ res.node = try p.addNode(.{
+ .tag = .union_init_expr,
+ .ty = dest_ty,
+ .data = .{ .union_init = .{ .field_index = 0, .node = res.node } },
+ });
+ res.ty = dest_ty;
+ return;
+ }
+ };
+ } else if (unqual_ty.is(.vector)) {
+ if (unqual_ty.eql(res.ty, p.comp, false)) {
+ return; // ok
+ }
+ } else {
+ if (ctx == .assign and (unqual_ty.isArray() or unqual_ty.isFunc())) {
+ try p.errTok(.not_assignable, tok);
+ return;
+ } else if (ctx == .test_coerce) {
+ return error.CoercionFailed;
+ }
+ // This case should not be possible and an error should have already been emitted but we
+ // might still have attempted to parse further so return error.ParsingFailed here to stop.
+ return error.ParsingFailed;
+ }
+
+ try p.errStr(switch (ctx) {
+ .assign => .incompatible_assign,
+ .init => .incompatible_init,
+ .ret => .incompatible_return,
+ .arg => .incompatible_arg,
+ .test_coerce => return error.CoercionFailed,
+ }, tok, try ctx.typePairStr(p, dest_ty, res.ty));
+ try ctx.note(p);
+ }
+};
+
+/// expr : assignExpr (',' assignExpr)*
+fn expr(p: *Parser) Error!Result {
+ var expr_start = p.tok_i;
+ var err_start = p.comp.diag.list.items.len;
+ var lhs = try p.assignExpr();
+ if (p.tok_ids[p.tok_i] == .comma) try lhs.expect(p);
+ while (p.eatToken(.comma)) |_| {
+ try lhs.maybeWarnUnused(p, expr_start, err_start);
+ expr_start = p.tok_i;
+ err_start = p.comp.diag.list.items.len;
+
+ var rhs = try p.assignExpr();
+ try rhs.expect(p);
+ try rhs.lvalConversion(p);
+ lhs.val = rhs.val;
+ lhs.ty = rhs.ty;
+ try lhs.bin(p, .comma_expr, rhs);
+ }
+ return lhs;
+}
+
+fn tokToTag(p: *Parser, tok: TokenIndex) Tree.Tag {
+ return switch (p.tok_ids[tok]) {
+ .equal => .assign_expr,
+ .asterisk_equal => .mul_assign_expr,
+ .slash_equal => .div_assign_expr,
+ .percent_equal => .mod_assign_expr,
+ .plus_equal => .add_assign_expr,
+ .minus_equal => .sub_assign_expr,
+ .angle_bracket_angle_bracket_left_equal => .shl_assign_expr,
+ .angle_bracket_angle_bracket_right_equal => .shr_assign_expr,
+ .ampersand_equal => .bit_and_assign_expr,
+ .caret_equal => .bit_xor_assign_expr,
+ .pipe_equal => .bit_or_assign_expr,
+ .equal_equal => .equal_expr,
+ .bang_equal => .not_equal_expr,
+ .angle_bracket_left => .less_than_expr,
+ .angle_bracket_left_equal => .less_than_equal_expr,
+ .angle_bracket_right => .greater_than_expr,
+ .angle_bracket_right_equal => .greater_than_equal_expr,
+ .angle_bracket_angle_bracket_left => .shl_expr,
+ .angle_bracket_angle_bracket_right => .shr_expr,
+ .plus => .add_expr,
+ .minus => .sub_expr,
+ .asterisk => .mul_expr,
+ .slash => .div_expr,
+ .percent => .mod_expr,
+ else => unreachable,
+ };
+}
+
+/// assignExpr
+/// : condExpr
+/// | unExpr ('=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=') assignExpr
+fn assignExpr(p: *Parser) Error!Result {
+ var lhs = try p.condExpr();
+ if (lhs.empty(p)) return lhs;
+
+ const tok = p.tok_i;
+ const eq = p.eatToken(.equal);
+ const mul = eq orelse p.eatToken(.asterisk_equal);
+ const div = mul orelse p.eatToken(.slash_equal);
+ const mod = div orelse p.eatToken(.percent_equal);
+ const add = mod orelse p.eatToken(.plus_equal);
+ const sub = add orelse p.eatToken(.minus_equal);
+ const shl = sub orelse p.eatToken(.angle_bracket_angle_bracket_left_equal);
+ const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right_equal);
+ const bit_and = shr orelse p.eatToken(.ampersand_equal);
+ const bit_xor = bit_and orelse p.eatToken(.caret_equal);
+ const bit_or = bit_xor orelse p.eatToken(.pipe_equal);
+
+ const tag = p.tokToTag(bit_or orelse return lhs);
+ var rhs = try p.assignExpr();
+ try rhs.expect(p);
+ try rhs.lvalConversion(p);
+
+ var is_const: bool = undefined;
+ if (!Tree.isLvalExtra(p.nodes.slice(), p.data.items, p.value_map, lhs.node, &is_const) or is_const) {
+ try p.errTok(.not_assignable, tok);
+ return error.ParsingFailed;
+ }
+
+ // adjustTypes will do do lvalue conversion but we do not want that
+ var lhs_copy = lhs;
+ switch (tag) {
+ .assign_expr => {}, // handle plain assignment separately
+ .mul_assign_expr,
+ .div_assign_expr,
+ .mod_assign_expr,
+ => {
+ if (rhs.val.isZero() and lhs.ty.isInt() and rhs.ty.isInt()) {
+ switch (tag) {
+ .div_assign_expr => try p.errStr(.division_by_zero, div.?, "division"),
+ .mod_assign_expr => try p.errStr(.division_by_zero, mod.?, "remainder"),
+ else => {},
+ }
+ }
+ _ = try lhs_copy.adjustTypes(tok, &rhs, p, if (tag == .mod_assign_expr) .integer else .arithmetic);
+ try lhs.bin(p, tag, rhs);
+ return lhs;
+ },
+ .sub_assign_expr,
+ .add_assign_expr,
+ => {
+ if (lhs.ty.isPtr() and rhs.ty.isInt()) {
+ try rhs.ptrCast(p, lhs.ty);
+ } else {
+ _ = try lhs_copy.adjustTypes(tok, &rhs, p, .arithmetic);
+ }
+ try lhs.bin(p, tag, rhs);
+ return lhs;
+ },
+ .shl_assign_expr,
+ .shr_assign_expr,
+ .bit_and_assign_expr,
+ .bit_xor_assign_expr,
+ .bit_or_assign_expr,
+ => {
+ _ = try lhs_copy.adjustTypes(tok, &rhs, p, .integer);
+ try lhs.bin(p, tag, rhs);
+ return lhs;
+ },
+ else => unreachable,
+ }
+
+ try rhs.coerce(p, lhs.ty, tok, .assign);
+
+ try lhs.bin(p, tag, rhs);
+ return lhs;
+}
+
+/// Returns a parse error if the expression is not an integer constant
+/// integerConstExpr : constExpr
+fn integerConstExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
+ const start = p.tok_i;
+ const res = try p.constExpr(decl_folding);
+ if (!res.ty.isInt() and res.ty.specifier != .invalid) {
+ try p.errTok(.expected_integer_constant_expr, start);
+ return error.ParsingFailed;
+ }
+ return res;
+}
+
+/// Caller is responsible for issuing a diagnostic if result is invalid/unavailable
+/// constExpr : condExpr
+fn constExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
+ const const_decl_folding = p.const_decl_folding;
+ defer p.const_decl_folding = const_decl_folding;
+ p.const_decl_folding = decl_folding;
+
+ const res = try p.condExpr();
+ try res.expect(p);
+
+ if (res.ty.specifier == .invalid or res.val.tag == .unavailable) return res;
+
+ // saveValue sets val to unavailable
+ var copy = res;
+ try copy.saveValue(p);
+ return res;
+}
+
+/// condExpr : lorExpr ('?' expression? ':' condExpr)?
+fn condExpr(p: *Parser) Error!Result {
+ const cond_tok = p.tok_i;
+ var cond = try p.lorExpr();
+ if (cond.empty(p) or p.eatToken(.question_mark) == null) return cond;
+ try cond.lvalConversion(p);
+ const saved_eval = p.no_eval;
+
+ if (!cond.ty.isScalar()) {
+ try p.errStr(.cond_expr_type, cond_tok, try p.typeStr(cond.ty));
+ return error.ParsingFailed;
+ }
+
+ // Prepare for possible binary conditional expression.
+ var maybe_colon = p.eatToken(.colon);
+
+ // Depending on the value of the condition, avoid evaluating unreachable branches.
+ var then_expr = blk: {
+ defer p.no_eval = saved_eval;
+ if (cond.val.tag != .unavailable and !cond.val.getBool()) p.no_eval = true;
+ break :blk try p.expr();
+ };
+ try then_expr.expect(p);
+
+ // If we saw a colon then this is a binary conditional expression.
+ if (maybe_colon) |colon| {
+ var cond_then = cond;
+ cond_then.node = try p.addNode(.{ .tag = .cond_dummy_expr, .ty = cond.ty, .data = .{ .un = cond.node } });
+ _ = try cond_then.adjustTypes(colon, &then_expr, p, .conditional);
+ cond.ty = then_expr.ty;
+ cond.node = try p.addNode(.{
+ .tag = .binary_cond_expr,
+ .ty = cond.ty,
+ .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ cond_then.node, then_expr.node })).start } },
+ });
+ return cond;
+ }
+
+ const colon = try p.expectToken(.colon);
+ var else_expr = blk: {
+ defer p.no_eval = saved_eval;
+ if (cond.val.tag != .unavailable and cond.val.getBool()) p.no_eval = true;
+ break :blk try p.condExpr();
+ };
+ try else_expr.expect(p);
+
+ _ = try then_expr.adjustTypes(colon, &else_expr, p, .conditional);
+
+ if (cond.val.tag != .unavailable) {
+ cond.val = if (cond.val.getBool()) then_expr.val else else_expr.val;
+ } else {
+ try then_expr.saveValue(p);
+ try else_expr.saveValue(p);
+ }
+ cond.ty = then_expr.ty;
+ cond.node = try p.addNode(.{
+ .tag = .cond_expr,
+ .ty = cond.ty,
+ .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
+ });
+ return cond;
+}
+
+/// lorExpr : landExpr ('||' landExpr)*
+fn lorExpr(p: *Parser) Error!Result {
+ var lhs = try p.landExpr();
+ if (lhs.empty(p)) return lhs;
+ const saved_eval = p.no_eval;
+ defer p.no_eval = saved_eval;
+
+ while (p.eatToken(.pipe_pipe)) |tok| {
+ if (lhs.val.tag != .unavailable and lhs.val.getBool()) p.no_eval = true;
+ var rhs = try p.landExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
+ const res = @intFromBool(lhs.val.getBool() or rhs.val.getBool());
+ lhs.val = Value.int(res);
+ }
+ try lhs.boolRes(p, .bool_or_expr, rhs);
+ }
+ return lhs;
+}
+
+/// landExpr : orExpr ('&&' orExpr)*
+fn landExpr(p: *Parser) Error!Result {
+ var lhs = try p.orExpr();
+ if (lhs.empty(p)) return lhs;
+ const saved_eval = p.no_eval;
+ defer p.no_eval = saved_eval;
+
+ while (p.eatToken(.ampersand_ampersand)) |tok| {
+ if (lhs.val.tag != .unavailable and !lhs.val.getBool()) p.no_eval = true;
+ var rhs = try p.orExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
+ const res = @intFromBool(lhs.val.getBool() and rhs.val.getBool());
+ lhs.val = Value.int(res);
+ }
+ try lhs.boolRes(p, .bool_and_expr, rhs);
+ }
+ return lhs;
+}
+
+/// orExpr : xorExpr ('|' xorExpr)*
+fn orExpr(p: *Parser) Error!Result {
+ var lhs = try p.xorExpr();
+ if (lhs.empty(p)) return lhs;
+ while (p.eatToken(.pipe)) |tok| {
+ var rhs = try p.xorExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
+ lhs.val = lhs.val.bitOr(rhs.val, lhs.ty, p.comp);
+ }
+ try lhs.bin(p, .bit_or_expr, rhs);
+ }
+ return lhs;
+}
+
+/// xorExpr : andExpr ('^' andExpr)*
+fn xorExpr(p: *Parser) Error!Result {
+ var lhs = try p.andExpr();
+ if (lhs.empty(p)) return lhs;
+ while (p.eatToken(.caret)) |tok| {
+ var rhs = try p.andExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
+ lhs.val = lhs.val.bitXor(rhs.val, lhs.ty, p.comp);
+ }
+ try lhs.bin(p, .bit_xor_expr, rhs);
+ }
+ return lhs;
+}
+
+/// andExpr : eqExpr ('&' eqExpr)*
+fn andExpr(p: *Parser) Error!Result {
+ var lhs = try p.eqExpr();
+ if (lhs.empty(p)) return lhs;
+ while (p.eatToken(.ampersand)) |tok| {
+ var rhs = try p.eqExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
+ lhs.val = lhs.val.bitAnd(rhs.val, lhs.ty, p.comp);
+ }
+ try lhs.bin(p, .bit_and_expr, rhs);
+ }
+ return lhs;
+}
+
+/// eqExpr : compExpr (('==' | '!=') compExpr)*
+fn eqExpr(p: *Parser) Error!Result {
+ var lhs = try p.compExpr();
+ if (lhs.empty(p)) return lhs;
+ while (true) {
+ const eq = p.eatToken(.equal_equal);
+ const ne = eq orelse p.eatToken(.bang_equal);
+ const tag = p.tokToTag(ne orelse break);
+ var rhs = try p.compExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(ne.?, &rhs, p, .equality)) {
+ const op: std.math.CompareOperator = if (tag == .equal_expr) .eq else .neq;
+ const res = lhs.val.compare(op, rhs.val, lhs.ty, p.comp);
+ lhs.val = Value.int(@intFromBool(res));
+ }
+ try lhs.boolRes(p, tag, rhs);
+ }
+ return lhs;
+}
+
+/// compExpr : shiftExpr (('<' | '<=' | '>' | '>=') shiftExpr)*
+fn compExpr(p: *Parser) Error!Result {
+ var lhs = try p.shiftExpr();
+ if (lhs.empty(p)) return lhs;
+ while (true) {
+ const lt = p.eatToken(.angle_bracket_left);
+ const le = lt orelse p.eatToken(.angle_bracket_left_equal);
+ const gt = le orelse p.eatToken(.angle_bracket_right);
+ const ge = gt orelse p.eatToken(.angle_bracket_right_equal);
+ const tag = p.tokToTag(ge orelse break);
+ var rhs = try p.shiftExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(ge.?, &rhs, p, .relational)) {
+ const op: std.math.CompareOperator = switch (tag) {
+ .less_than_expr => .lt,
+ .less_than_equal_expr => .lte,
+ .greater_than_expr => .gt,
+ .greater_than_equal_expr => .gte,
+ else => unreachable,
+ };
+ const res = lhs.val.compare(op, rhs.val, lhs.ty, p.comp);
+ lhs.val = Value.int(@intFromBool(res));
+ }
+ try lhs.boolRes(p, tag, rhs);
+ }
+ return lhs;
+}
+
+/// shiftExpr : addExpr (('<<' | '>>') addExpr)*
+fn shiftExpr(p: *Parser) Error!Result {
+ var lhs = try p.addExpr();
+ if (lhs.empty(p)) return lhs;
+ while (true) {
+ const shl = p.eatToken(.angle_bracket_angle_bracket_left);
+ const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right);
+ const tag = p.tokToTag(shr orelse break);
+ var rhs = try p.addExpr();
+ try rhs.expect(p);
+
+ if (try lhs.adjustTypes(shr.?, &rhs, p, .integer)) {
+ if (shl != null) {
+ lhs.val = lhs.val.shl(rhs.val, lhs.ty, p.comp);
+ } else {
+ lhs.val = lhs.val.shr(rhs.val, lhs.ty, p.comp);
+ }
+ }
+ try lhs.bin(p, tag, rhs);
+ }
+ return lhs;
+}
+
+/// addExpr : mulExpr (('+' | '-') mulExpr)*
+fn addExpr(p: *Parser) Error!Result {
+ var lhs = try p.mulExpr();
+ if (lhs.empty(p)) return lhs;
+ while (true) {
+ const plus = p.eatToken(.plus);
+ const minus = plus orelse p.eatToken(.minus);
+ const tag = p.tokToTag(minus orelse break);
+ var rhs = try p.mulExpr();
+ try rhs.expect(p);
+
+ const lhs_ty = lhs.ty;
+ if (try lhs.adjustTypes(minus.?, &rhs, p, if (plus != null) .add else .sub)) {
+ if (plus != null) {
+ if (lhs.val.add(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(plus.?, lhs);
+ } else {
+ if (lhs.val.sub(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(minus.?, lhs);
+ }
+ }
+ if (lhs.ty.specifier != .invalid and lhs_ty.isPtr() and !lhs_ty.isVoidStar() and lhs_ty.elemType().hasIncompleteSize()) {
+ try p.errStr(.ptr_arithmetic_incomplete, minus.?, try p.typeStr(lhs_ty.elemType()));
+ lhs.ty = Type.invalid;
+ }
+ try lhs.bin(p, tag, rhs);
+ }
+ return lhs;
+}
+
+/// mulExpr : castExpr (('*' | '/' | '%') castExpr)*ยด
+fn mulExpr(p: *Parser) Error!Result {
+ var lhs = try p.castExpr();
+ if (lhs.empty(p)) return lhs;
+ while (true) {
+ const mul = p.eatToken(.asterisk);
+ const div = mul orelse p.eatToken(.slash);
+ const percent = div orelse p.eatToken(.percent);
+ const tag = p.tokToTag(percent orelse break);
+ var rhs = try p.castExpr();
+ try rhs.expect(p);
+
+ if (rhs.val.isZero() and mul == null and !p.no_eval and lhs.ty.isInt() and rhs.ty.isInt()) {
+ const err_tag: Diagnostics.Tag = if (p.in_macro) .division_by_zero_macro else .division_by_zero;
+ lhs.val.tag = .unavailable;
+ if (div != null) {
+ try p.errStr(err_tag, div.?, "division");
+ } else {
+ try p.errStr(err_tag, percent.?, "remainder");
+ }
+ if (p.in_macro) return error.ParsingFailed;
+ }
+
+ if (try lhs.adjustTypes(percent.?, &rhs, p, if (tag == .mod_expr) .integer else .arithmetic)) {
+ if (mul != null) {
+ if (lhs.val.mul(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs);
+ } else if (div != null) {
+ lhs.val = Value.div(lhs.val, rhs.val, lhs.ty, p.comp);
+ } else {
+ var res = Value.rem(lhs.val, rhs.val, lhs.ty, p.comp);
+ if (res.tag == .unavailable) {
+ if (p.in_macro) {
+ // match clang behavior by defining invalid remainder to be zero in macros
+ res = Value.int(0);
+ } else {
+ try lhs.saveValue(p);
+ try rhs.saveValue(p);
+ }
+ }
+ lhs.val = res;
+ }
+ }
+
+ try lhs.bin(p, tag, rhs);
+ }
+ return lhs;
+}
+
+/// This will always be the last message, if present
+fn removeUnusedWarningForTok(p: *Parser, last_expr_tok: TokenIndex) void {
+ if (last_expr_tok == 0) return;
+ if (p.comp.diag.list.items.len == 0) return;
+
+ const last_expr_loc = p.pp.tokens.items(.loc)[last_expr_tok];
+ const last_msg = p.comp.diag.list.items[p.comp.diag.list.items.len - 1];
+
+ if (last_msg.tag == .unused_value and last_msg.loc.eql(last_expr_loc)) {
+ p.comp.diag.list.items.len = p.comp.diag.list.items.len - 1;
+ }
+}
+
+/// castExpr
+/// : '(' compoundStmt ')'
+/// | '(' typeName ')' castExpr
+/// | '(' typeName ')' '{' initializerItems '}'
+/// | __builtin_choose_expr '(' integerConstExpr ',' assignExpr ',' assignExpr ')'
+/// | __builtin_va_arg '(' assignExpr ',' typeName ')'
+/// | __builtin_offsetof '(' typeName ',' offsetofMemberDesignator ')'
+/// | __builtin_bitoffsetof '(' typeName ',' offsetofMemberDesignator ')'
+/// | unExpr
+fn castExpr(p: *Parser) Error!Result {
+ if (p.eatToken(.l_paren)) |l_paren| cast_expr: {
+ if (p.tok_ids[p.tok_i] == .l_brace) {
+ try p.err(.gnu_statement_expression);
+ if (p.func.ty == null) {
+ try p.err(.stmt_expr_not_allowed_file_scope);
+ return error.ParsingFailed;
+ }
+ var stmt_expr_state: StmtExprState = .{};
+ const body_node = (try p.compoundStmt(false, &stmt_expr_state)).?; // compoundStmt only returns null if .l_brace isn't the first token
+ p.removeUnusedWarningForTok(stmt_expr_state.last_expr_tok);
+
+ var res = Result{
+ .node = body_node,
+ .ty = stmt_expr_state.last_expr_res.ty,
+ .val = stmt_expr_state.last_expr_res.val,
+ };
+ try p.expectClosing(l_paren, .r_paren);
+ try res.un(p, .stmt_expr);
+ return res;
+ }
+ const ty = (try p.typeName()) orelse {
+ p.tok_i -= 1;
+ break :cast_expr;
+ };
+ try p.expectClosing(l_paren, .r_paren);
+
+ if (p.tok_ids[p.tok_i] == .l_brace) {
+ // Compound literal; handled in unExpr
+ p.tok_i = l_paren;
+ break :cast_expr;
+ }
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ try operand.lvalConversion(p);
+ try operand.castType(p, ty, l_paren);
+ return operand;
+ }
+ switch (p.tok_ids[p.tok_i]) {
+ .builtin_choose_expr => return p.builtinChooseExpr(),
+ .builtin_va_arg => return p.builtinVaArg(),
+ .builtin_offsetof => return p.builtinOffsetof(false),
+ .builtin_bitoffsetof => return p.builtinOffsetof(true),
+ .builtin_types_compatible_p => return p.typesCompatible(),
+ // TODO: other special-cased builtins
+ else => {},
+ }
+ return p.unExpr();
+}
+
+fn typesCompatible(p: *Parser) Error!Result {
+ p.tok_i += 1;
+ const l_paren = try p.expectToken(.l_paren);
+
+ const first = (try p.typeName()) orelse {
+ try p.err(.expected_type);
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ };
+ const lhs = try p.addNode(.{ .tag = .invalid, .ty = first, .data = undefined });
+ _ = try p.expectToken(.comma);
+
+ const second = (try p.typeName()) orelse {
+ try p.err(.expected_type);
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ };
+ const rhs = try p.addNode(.{ .tag = .invalid, .ty = second, .data = undefined });
+
+ try p.expectClosing(l_paren, .r_paren);
+
+ const compatible = first.compatible(second, p.comp);
+
+ var res = Result{
+ .val = Value.int(@intFromBool(compatible)),
+ .node = try p.addNode(.{ .tag = .builtin_types_compatible_p, .ty = Type.int, .data = .{ .bin = .{
+ .lhs = lhs,
+ .rhs = rhs,
+ } } }),
+ };
+ try p.value_map.put(res.node, res.val);
+ return res;
+}
+
+fn builtinChooseExpr(p: *Parser) Error!Result {
+ p.tok_i += 1;
+ const l_paren = try p.expectToken(.l_paren);
+ const cond_tok = p.tok_i;
+ var cond = try p.integerConstExpr(.no_const_decl_folding);
+ if (cond.val.tag == .unavailable) {
+ try p.errTok(.builtin_choose_cond, cond_tok);
+ return error.ParsingFailed;
+ }
+
+ _ = try p.expectToken(.comma);
+
+ var then_expr = if (cond.val.getBool()) try p.assignExpr() else try p.parseNoEval(assignExpr);
+ try then_expr.expect(p);
+
+ _ = try p.expectToken(.comma);
+
+ var else_expr = if (!cond.val.getBool()) try p.assignExpr() else try p.parseNoEval(assignExpr);
+ try else_expr.expect(p);
+
+ try p.expectClosing(l_paren, .r_paren);
+
+ if (cond.val.getBool()) {
+ cond.val = then_expr.val;
+ cond.ty = then_expr.ty;
+ } else {
+ cond.val = else_expr.val;
+ cond.ty = else_expr.ty;
+ }
+ cond.node = try p.addNode(.{
+ .tag = .builtin_choose_expr,
+ .ty = cond.ty,
+ .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
+ });
+ return cond;
+}
+
+fn builtinVaArg(p: *Parser) Error!Result {
+ const builtin_tok = p.tok_i;
+ p.tok_i += 1;
+
+ const l_paren = try p.expectToken(.l_paren);
+ const va_list_tok = p.tok_i;
+ var va_list = try p.assignExpr();
+ try va_list.expect(p);
+ try va_list.lvalConversion(p);
+
+ _ = try p.expectToken(.comma);
+
+ const ty = (try p.typeName()) orelse {
+ try p.err(.expected_type);
+ return error.ParsingFailed;
+ };
+ try p.expectClosing(l_paren, .r_paren);
+
+ if (!va_list.ty.eql(p.comp.types.va_list, p.comp, true)) {
+ try p.errStr(.incompatible_va_arg, va_list_tok, try p.typeStr(va_list.ty));
+ return error.ParsingFailed;
+ }
+
+ return Result{ .ty = ty, .node = try p.addNode(.{
+ .tag = .special_builtin_call_one,
+ .ty = ty,
+ .data = .{ .decl = .{ .name = builtin_tok, .node = va_list.node } },
+ }) };
+}
+
+fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result {
+ const builtin_tok = p.tok_i;
+ p.tok_i += 1;
+
+ const l_paren = try p.expectToken(.l_paren);
+ const ty_tok = p.tok_i;
+
+ const ty = (try p.typeName()) orelse {
+ try p.err(.expected_type);
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ };
+
+ if (!ty.isRecord()) {
+ try p.errStr(.offsetof_ty, ty_tok, try p.typeStr(ty));
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ } else if (ty.hasIncompleteSize()) {
+ try p.errStr(.offsetof_incomplete, ty_tok, try p.typeStr(ty));
+ p.skipTo(.r_paren);
+ return error.ParsingFailed;
+ }
+
+ _ = try p.expectToken(.comma);
+
+ const offsetof_expr = try p.offsetofMemberDesignator(ty);
+
+ try p.expectClosing(l_paren, .r_paren);
+
+ return Result{
+ .ty = p.comp.types.size,
+ .val = if (offsetof_expr.val.tag == .int and !want_bits)
+ Value.int(offsetof_expr.val.data.int / 8)
+ else
+ offsetof_expr.val,
+ .node = try p.addNode(.{
+ .tag = .special_builtin_call_one,
+ .ty = p.comp.types.size,
+ .data = .{ .decl = .{ .name = builtin_tok, .node = offsetof_expr.node } },
+ }),
+ };
+}
+
+/// offsetofMemberDesignator: IDENTIFIER ('.' IDENTIFIER | '[' expr ']' )*
+fn offsetofMemberDesignator(p: *Parser, base_ty: Type) Error!Result {
+ errdefer p.skipTo(.r_paren);
+ const base_field_name_tok = try p.expectIdentifier();
+ const base_field_name = try p.comp.intern(p.tokSlice(base_field_name_tok));
+ try p.validateFieldAccess(base_ty, base_ty, base_field_name_tok, base_field_name);
+ const base_node = try p.addNode(.{ .tag = .default_init_expr, .ty = base_ty, .data = undefined });
+
+ var offset_num: u64 = 0;
+ const base_record_ty = base_ty.canonicalize(.standard);
+ var lhs = try p.fieldAccessExtra(base_node, base_record_ty, base_field_name, false, &offset_num);
+ var bit_offset = Value.int(offset_num);
+
+ while (true) switch (p.tok_ids[p.tok_i]) {
+ .period => {
+ p.tok_i += 1;
+ const field_name_tok = try p.expectIdentifier();
+ const field_name = try p.comp.intern(p.tokSlice(field_name_tok));
+
+ if (!lhs.ty.isRecord()) {
+ try p.errStr(.offsetof_ty, field_name_tok, try p.typeStr(lhs.ty));
+ return error.ParsingFailed;
+ }
+ try p.validateFieldAccess(lhs.ty, lhs.ty, field_name_tok, field_name);
+ const record_ty = lhs.ty.canonicalize(.standard);
+ lhs = try p.fieldAccessExtra(lhs.node, record_ty, field_name, false, &offset_num);
+ if (bit_offset.tag != .unavailable) {
+ bit_offset = Value.int(offset_num + bit_offset.getInt(u64));
+ }
+ },
+ .l_bracket => {
+ const l_bracket_tok = p.tok_i;
+ p.tok_i += 1;
+ var index = try p.expr();
+ try index.expect(p);
+ _ = try p.expectClosing(l_bracket_tok, .r_bracket);
+
+ if (!lhs.ty.isArray()) {
+ try p.errStr(.offsetof_array, l_bracket_tok, try p.typeStr(lhs.ty));
+ return error.ParsingFailed;
+ }
+ var ptr = lhs;
+ try ptr.lvalConversion(p);
+ try index.lvalConversion(p);
+
+ if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket_tok);
+ try p.checkArrayBounds(index, lhs, l_bracket_tok);
+
+ try index.saveValue(p);
+ try ptr.bin(p, .array_access_expr, index);
+ lhs = ptr;
+ },
+ else => break,
+ };
+
+ return Result{ .ty = base_ty, .val = bit_offset, .node = lhs.node };
+}
+
+/// unExpr
+/// : (compoundLiteral | primaryExpr) suffixExpr*
+/// | '&&' IDENTIFIER
+/// | ('&' | '*' | '+' | '-' | '~' | '!' | '++' | '--' | keyword_extension | keyword_imag | keyword_real) castExpr
+/// | keyword_sizeof unExpr
+/// | keyword_sizeof '(' typeName ')'
+/// | keyword_alignof '(' typeName ')'
+/// | keyword_c23_alignof '(' typeName ')'
+fn unExpr(p: *Parser) Error!Result {
+ const tok = p.tok_i;
+ switch (p.tok_ids[tok]) {
+ .ampersand_ampersand => {
+ const address_tok = p.tok_i;
+ p.tok_i += 1;
+ const name_tok = try p.expectIdentifier();
+ try p.errTok(.gnu_label_as_value, address_tok);
+ p.contains_address_of_label = true;
+
+ const str = p.tokSlice(name_tok);
+ if (p.findLabel(str) == null) {
+ try p.labels.append(.{ .unresolved_goto = name_tok });
+ }
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = .{ .specifier = .void };
+ const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
+ return Result{
+ .node = try p.addNode(.{
+ .tag = .addr_of_label,
+ .data = .{ .decl_ref = name_tok },
+ .ty = result_ty,
+ }),
+ .ty = result_ty,
+ };
+ },
+ .ampersand => {
+ if (p.in_macro) {
+ try p.err(.invalid_preproc_operator);
+ return error.ParsingFailed;
+ }
+ p.tok_i += 1;
+ var operand = try p.castExpr();
+ try operand.expect(p);
+
+ const slice = p.nodes.slice();
+ if (p.getNode(operand.node, .member_access_expr) orelse p.getNode(operand.node, .member_access_ptr_expr)) |member_node| {
+ if (Tree.isBitfield(slice, member_node)) try p.errTok(.addr_of_bitfield, tok);
+ }
+ if (!Tree.isLval(slice, p.data.items, p.value_map, operand.node)) {
+ try p.errTok(.addr_of_rvalue, tok);
+ }
+ if (operand.ty.qual.register) try p.errTok(.addr_of_register, tok);
+
+ const elem_ty = try p.arena.create(Type);
+ elem_ty.* = operand.ty;
+ operand.ty = Type{
+ .specifier = .pointer,
+ .data = .{ .sub_type = elem_ty },
+ };
+ try operand.saveValue(p);
+ try operand.un(p, .addr_of_expr);
+ return operand;
+ },
+ .asterisk => {
+ const asterisk_loc = p.tok_i;
+ p.tok_i += 1;
+ var operand = try p.castExpr();
+ try operand.expect(p);
+
+ if (operand.ty.isArray() or operand.ty.isPtr() or operand.ty.isFunc()) {
+ try operand.lvalConversion(p);
+ operand.ty = operand.ty.elemType();
+ } else {
+ try p.errTok(.indirection_ptr, tok);
+ }
+ if (operand.ty.hasIncompleteSize() and !operand.ty.is(.void)) {
+ try p.errStr(.deref_incomplete_ty_ptr, asterisk_loc, try p.typeStr(operand.ty));
+ }
+ operand.ty.qual = .{};
+ try operand.un(p, .deref_expr);
+ return operand;
+ },
+ .plus => {
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ try operand.lvalConversion(p);
+ if (!operand.ty.isInt() and !operand.ty.isFloat())
+ try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+
+ try operand.usualUnaryConversion(p, tok);
+
+ return operand;
+ },
+ .minus => {
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ try operand.lvalConversion(p);
+ if (!operand.ty.isInt() and !operand.ty.isFloat())
+ try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+
+ try operand.usualUnaryConversion(p, tok);
+ if (operand.val.tag == .int or operand.val.tag == .float) {
+ _ = operand.val.sub(operand.val.zero(), operand.val, operand.ty, p.comp);
+ } else {
+ operand.val.tag = .unavailable;
+ }
+ try operand.un(p, .negate_expr);
+ return operand;
+ },
+ .plus_plus => {
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ if (!operand.ty.isScalar())
+ try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+ if (operand.ty.isComplex())
+ try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+ if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+ try p.errTok(.not_assignable, tok);
+ return error.ParsingFailed;
+ }
+ try operand.usualUnaryConversion(p, tok);
+
+ if (operand.val.tag == .int or operand.val.tag == .float) {
+ if (operand.val.add(operand.val, operand.val.one(), operand.ty, p.comp))
+ try p.errOverflow(tok, operand);
+ } else {
+ operand.val.tag = .unavailable;
+ }
+
+ try operand.un(p, .pre_inc_expr);
+ return operand;
+ },
+ .minus_minus => {
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ if (!operand.ty.isScalar())
+ try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+ if (operand.ty.isComplex())
+ try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+ if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+ try p.errTok(.not_assignable, tok);
+ return error.ParsingFailed;
+ }
+ try operand.usualUnaryConversion(p, tok);
+
+ if (operand.val.tag == .int or operand.val.tag == .float) {
+ if (operand.val.sub(operand.val, operand.val.one(), operand.ty, p.comp))
+ try p.errOverflow(tok, operand);
+ } else {
+ operand.val.tag = .unavailable;
+ }
+
+ try operand.un(p, .pre_dec_expr);
+ return operand;
+ },
+ .tilde => {
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ try operand.lvalConversion(p);
+ try operand.usualUnaryConversion(p, tok);
+ if (operand.ty.isInt()) {
+ if (operand.val.tag == .int) {
+ operand.val = operand.val.bitNot(operand.ty, p.comp);
+ }
+ } else {
+ try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+ operand.val.tag = .unavailable;
+ }
+ try operand.un(p, .bit_not_expr);
+ return operand;
+ },
+ .bang => {
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ try operand.lvalConversion(p);
+ if (!operand.ty.isScalar())
+ try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+
+ try operand.usualUnaryConversion(p, tok);
+ if (operand.val.tag == .int) {
+ const res = Value.int(@intFromBool(!operand.val.getBool()));
+ operand.val = res;
+ } else if (operand.val.tag == .nullptr_t) {
+ operand.val = Value.int(1);
+ } else {
+ if (operand.ty.isDecayed()) {
+ operand.val = Value.int(0);
+ } else {
+ operand.val.tag = .unavailable;
+ }
+ }
+ operand.ty = .{ .specifier = .int };
+ try operand.un(p, .bool_not_expr);
+ return operand;
+ },
+ .keyword_sizeof => {
+ p.tok_i += 1;
+ const expected_paren = p.tok_i;
+ var res = Result{};
+ if (try p.typeName()) |ty| {
+ res.ty = ty;
+ try p.errTok(.expected_parens_around_typename, expected_paren);
+ } else if (p.eatToken(.l_paren)) |l_paren| {
+ if (try p.typeName()) |ty| {
+ res.ty = ty;
+ try p.expectClosing(l_paren, .r_paren);
+ } else {
+ p.tok_i = expected_paren;
+ res = try p.parseNoEval(unExpr);
+ }
+ } else {
+ res = try p.parseNoEval(unExpr);
+ }
+
+ if (res.ty.is(.void)) {
+ try p.errStr(.pointer_arith_void, tok, "sizeof");
+ } else if (res.ty.isDecayed()) {
+ const array_ty = res.ty.originalTypeOfDecayedArray();
+ const err_str = try p.typePairStrExtra(res.ty, " instead of ", array_ty);
+ try p.errStr(.sizeof_array_arg, tok, err_str);
+ }
+ if (res.ty.sizeof(p.comp)) |size| {
+ if (size == 0) {
+ try p.errTok(.sizeof_returns_zero, tok);
+ }
+ res.val = Value.int(size);
+ res.ty = p.comp.types.size;
+ } else {
+ res.val.tag = .unavailable;
+ if (res.ty.hasIncompleteSize()) {
+ try p.errStr(.invalid_sizeof, expected_paren - 1, try p.typeStr(res.ty));
+ res.ty = Type.invalid;
+ } else {
+ res.ty = p.comp.types.size;
+ }
+ }
+ try res.un(p, .sizeof_expr);
+ return res;
+ },
+ .keyword_alignof,
+ .keyword_alignof1,
+ .keyword_alignof2,
+ .keyword_c23_alignof,
+ => {
+ p.tok_i += 1;
+ const expected_paren = p.tok_i;
+ var res = Result{};
+ if (try p.typeName()) |ty| {
+ res.ty = ty;
+ try p.errTok(.expected_parens_around_typename, expected_paren);
+ } else if (p.eatToken(.l_paren)) |l_paren| {
+ if (try p.typeName()) |ty| {
+ res.ty = ty;
+ try p.expectClosing(l_paren, .r_paren);
+ } else {
+ p.tok_i = expected_paren;
+ res = try p.parseNoEval(unExpr);
+ try p.errTok(.alignof_expr, expected_paren);
+ }
+ } else {
+ res = try p.parseNoEval(unExpr);
+ try p.errTok(.alignof_expr, expected_paren);
+ }
+
+ if (res.ty.is(.void)) {
+ try p.errStr(.pointer_arith_void, tok, "alignof");
+ }
+ if (res.ty.alignable()) {
+ res.val = Value.int(res.ty.alignof(p.comp));
+ res.ty = p.comp.types.size;
+ } else {
+ try p.errStr(.invalid_alignof, expected_paren, try p.typeStr(res.ty));
+ res.ty = Type.invalid;
+ }
+ try res.un(p, .alignof_expr);
+ return res;
+ },
+ .keyword_extension => {
+ p.tok_i += 1;
+ const saved_extension = p.extension_suppressed;
+ defer p.extension_suppressed = saved_extension;
+ p.extension_suppressed = true;
+
+ var child = try p.castExpr();
+ try child.expect(p);
+ return child;
+ },
+ .keyword_imag1, .keyword_imag2 => {
+ const imag_tok = p.tok_i;
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ try operand.lvalConversion(p);
+ if (!operand.ty.isInt() and !operand.ty.isFloat()) {
+ try p.errStr(.invalid_imag, imag_tok, try p.typeStr(operand.ty));
+ }
+ if (operand.ty.isReal()) {
+ switch (p.comp.langopts.emulate) {
+ .msvc => {}, // Doesn't support `_Complex` or `__imag` in the first place
+ .gcc => {
+ if (operand.ty.isInt()) {
+ operand.val = Value.int(0);
+ } else if (operand.ty.isFloat()) {
+ operand.val = Value.float(0);
+ }
+ },
+ .clang => {
+ if (operand.val.tag == .int) {
+ operand.val = Value.int(0);
+ } else {
+ operand.val.tag = .unavailable;
+ }
+ },
+ }
+ }
+ // convert _Complex T to T
+ operand.ty = operand.ty.makeReal();
+ try operand.un(p, .imag_expr);
+ return operand;
+ },
+ .keyword_real1, .keyword_real2 => {
+ const real_tok = p.tok_i;
+ p.tok_i += 1;
+
+ var operand = try p.castExpr();
+ try operand.expect(p);
+ try operand.lvalConversion(p);
+ if (!operand.ty.isInt() and !operand.ty.isFloat()) {
+ try p.errStr(.invalid_real, real_tok, try p.typeStr(operand.ty));
+ }
+ // convert _Complex T to T
+ operand.ty = operand.ty.makeReal();
+ try operand.un(p, .real_expr);
+ return operand;
+ },
+ else => {
+ var lhs = try p.compoundLiteral();
+ if (lhs.empty(p)) {
+ lhs = try p.primaryExpr();
+ if (lhs.empty(p)) return lhs;
+ }
+ while (true) {
+ const suffix = try p.suffixExpr(lhs);
+ if (suffix.empty(p)) break;
+ lhs = suffix;
+ }
+ return lhs;
+ },
+ }
+}
+
+/// compoundLiteral
+/// : '(' type_name ')' '{' initializer_list '}'
+/// | '(' type_name ')' '{' initializer_list ',' '}'
+fn compoundLiteral(p: *Parser) Error!Result {
+ const l_paren = p.eatToken(.l_paren) orelse return Result{};
+ const ty = (try p.typeName()) orelse {
+ p.tok_i = l_paren;
+ return Result{};
+ };
+ try p.expectClosing(l_paren, .r_paren);
+
+ if (ty.isFunc()) {
+ try p.err(.func_init);
+ } else if (ty.is(.variable_len_array)) {
+ try p.err(.vla_init);
+ } else if (ty.hasIncompleteSize() and !ty.is(.incomplete_array)) {
+ try p.errStr(.variable_incomplete_ty, p.tok_i, try p.typeStr(ty));
+ return error.ParsingFailed;
+ }
+ var init_list_expr = try p.initializer(ty);
+ try init_list_expr.un(p, .compound_literal_expr);
+ return init_list_expr;
+}
+
+/// suffixExpr
+/// : '[' expr ']'
+/// | '(' argumentExprList? ')'
+/// | '.' IDENTIFIER
+/// | '->' IDENTIFIER
+/// | '++'
+/// | '--'
+/// argumentExprList : assignExpr (',' assignExpr)*
+fn suffixExpr(p: *Parser, lhs: Result) Error!Result {
+ assert(!lhs.empty(p));
+ switch (p.tok_ids[p.tok_i]) {
+ .l_paren => return p.callExpr(lhs),
+ .plus_plus => {
+ defer p.tok_i += 1;
+
+ var operand = lhs;
+ if (!operand.ty.isScalar())
+ try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
+ if (operand.ty.isComplex())
+ try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+ if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+ try p.err(.not_assignable);
+ return error.ParsingFailed;
+ }
+ try operand.usualUnaryConversion(p, p.tok_i);
+
+ try operand.un(p, .post_inc_expr);
+ return operand;
+ },
+ .minus_minus => {
+ defer p.tok_i += 1;
+
+ var operand = lhs;
+ if (!operand.ty.isScalar())
+ try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
+ if (operand.ty.isComplex())
+ try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+ if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+ try p.err(.not_assignable);
+ return error.ParsingFailed;
+ }
+ try operand.usualUnaryConversion(p, p.tok_i);
+
+ try operand.un(p, .post_dec_expr);
+ return operand;
+ },
+ .l_bracket => {
+ const l_bracket = p.tok_i;
+ p.tok_i += 1;
+ var index = try p.expr();
+ try index.expect(p);
+ try p.expectClosing(l_bracket, .r_bracket);
+
+ const array_before_conversion = lhs;
+ const index_before_conversion = index;
+ var ptr = lhs;
+ try ptr.lvalConversion(p);
+ try index.lvalConversion(p);
+ if (ptr.ty.isPtr()) {
+ ptr.ty = ptr.ty.elemType();
+ if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
+ try p.checkArrayBounds(index_before_conversion, array_before_conversion, l_bracket);
+ } else if (index.ty.isPtr()) {
+ index.ty = index.ty.elemType();
+ if (!ptr.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
+ try p.checkArrayBounds(array_before_conversion, index_before_conversion, l_bracket);
+ std.mem.swap(Result, &ptr, &index);
+ } else {
+ try p.errTok(.invalid_subscript, l_bracket);
+ }
+
+ try ptr.saveValue(p);
+ try index.saveValue(p);
+ try ptr.bin(p, .array_access_expr, index);
+ return ptr;
+ },
+ .period => {
+ p.tok_i += 1;
+ const name = try p.expectIdentifier();
+ return p.fieldAccess(lhs, name, false);
+ },
+ .arrow => {
+ p.tok_i += 1;
+ const name = try p.expectIdentifier();
+ if (lhs.ty.isArray()) {
+ var copy = lhs;
+ copy.ty.decayArray();
+ try copy.implicitCast(p, .array_to_pointer);
+ return p.fieldAccess(copy, name, true);
+ }
+ return p.fieldAccess(lhs, name, true);
+ },
+ else => return Result{},
+ }
+}
+
+fn fieldAccess(
+ p: *Parser,
+ lhs: Result,
+ field_name_tok: TokenIndex,
+ is_arrow: bool,
+) !Result {
+ const expr_ty = lhs.ty;
+ const is_ptr = expr_ty.isPtr();
+ const expr_base_ty = if (is_ptr) expr_ty.elemType() else expr_ty;
+ const record_ty = expr_base_ty.canonicalize(.standard);
+
+ switch (record_ty.specifier) {
+ .@"struct", .@"union" => {},
+ else => {
+ try p.errStr(.expected_record_ty, field_name_tok, try p.typeStr(expr_ty));
+ return error.ParsingFailed;
+ },
+ }
+ if (record_ty.hasIncompleteSize()) {
+ try p.errStr(.deref_incomplete_ty_ptr, field_name_tok - 2, try p.typeStr(expr_base_ty));
+ return error.ParsingFailed;
+ }
+ if (is_arrow and !is_ptr) try p.errStr(.member_expr_not_ptr, field_name_tok, try p.typeStr(expr_ty));
+ if (!is_arrow and is_ptr) try p.errStr(.member_expr_ptr, field_name_tok, try p.typeStr(expr_ty));
+
+ const field_name = try p.comp.intern(p.tokSlice(field_name_tok));
+ try p.validateFieldAccess(record_ty, expr_ty, field_name_tok, field_name);
+ var discard: u64 = 0;
+ return p.fieldAccessExtra(lhs.node, record_ty, field_name, is_arrow, &discard);
+}
+
+fn validateFieldAccess(p: *Parser, record_ty: Type, expr_ty: Type, field_name_tok: TokenIndex, field_name: StringId) Error!void {
+ if (record_ty.hasField(field_name)) return;
+
+ p.strings.items.len = 0;
+
+ try p.strings.writer().print("'{s}' in '", .{p.tokSlice(field_name_tok)});
+ const mapper = p.comp.string_interner.getSlowTypeMapper();
+ try expr_ty.print(mapper, p.comp.langopts, p.strings.writer());
+ try p.strings.append('\'');
+
+ const duped = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items);
+ try p.errStr(.no_such_member, field_name_tok, duped);
+ return error.ParsingFailed;
+}
+
+fn fieldAccessExtra(p: *Parser, lhs: NodeIndex, record_ty: Type, field_name: StringId, is_arrow: bool, offset_bits: *u64) Error!Result {
+ for (record_ty.data.record.fields, 0..) |f, i| {
+ if (f.isAnonymousRecord()) {
+ if (!f.ty.hasField(field_name)) continue;
+ const inner = try p.addNode(.{
+ .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
+ .ty = f.ty,
+ .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
+ });
+ const ret = p.fieldAccessExtra(inner, f.ty, field_name, false, offset_bits);
+ offset_bits.* += f.layout.offset_bits;
+ return ret;
+ }
+ if (field_name == f.name) {
+ offset_bits.* = f.layout.offset_bits;
+ return Result{
+ .ty = f.ty,
+ .node = try p.addNode(.{
+ .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
+ .ty = f.ty,
+ .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
+ }),
+ };
+ }
+ }
+ // We already checked that this container has a field by the name.
+ unreachable;
+}
+
+fn checkVaStartArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
+ assert(idx != 0);
+ if (idx > 1) {
+ try p.errTok(.closing_paren, first_after);
+ return error.ParsingFailed;
+ }
+
+ var func_ty = p.func.ty orelse {
+ try p.errTok(.va_start_not_in_func, builtin_tok);
+ return;
+ };
+ const func_params = func_ty.params();
+ if (func_ty.specifier != .var_args_func or func_params.len == 0) {
+ return p.errTok(.va_start_fixed_args, builtin_tok);
+ }
+ const last_param_name = func_params[func_params.len - 1].name;
+ const decl_ref = p.getNode(arg.node, .decl_ref_expr);
+ if (decl_ref == null or last_param_name != try p.comp.intern(p.tokSlice(p.nodes.items(.data)[@intFromEnum(decl_ref.?)].decl_ref))) {
+ try p.errTok(.va_start_not_last_param, param_tok);
+ }
+}
+
+fn checkComplexArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
+ _ = builtin_tok;
+ _ = first_after;
+ if (idx <= 1 and !arg.ty.isFloat()) {
+ try p.errStr(.not_floating_type, param_tok, try p.typeStr(arg.ty));
+ } else if (idx == 1) {
+ const prev_idx = p.list_buf.items[p.list_buf.items.len - 1];
+ const prev_ty = p.nodes.items(.ty)[@intFromEnum(prev_idx)];
+ if (!prev_ty.eql(arg.ty, p.comp, false)) {
+ try p.errStr(.argument_types_differ, param_tok, try p.typePairStrExtra(prev_ty, " vs ", arg.ty));
+ }
+ }
+}
+
+fn checkVariableBuiltinArgument(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32, tag: BuiltinFunction.Tag) !void {
+ switch (tag) {
+ .__builtin_va_start, .__va_start, .va_start => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx),
+ else => {},
+ }
+}
+
+fn callExpr(p: *Parser, lhs: Result) Error!Result {
+ const l_paren = p.tok_i;
+ p.tok_i += 1;
+ const ty = lhs.ty.isCallable() orelse {
+ try p.errStr(.not_callable, l_paren, try p.typeStr(lhs.ty));
+ return error.ParsingFailed;
+ };
+ const params = ty.params();
+ var func = lhs;
+ try func.lvalConversion(p);
+
+ const list_buf_top = p.list_buf.items.len;
+ defer p.list_buf.items.len = list_buf_top;
+ try p.list_buf.append(func.node);
+ var arg_count: u32 = 0;
+ var first_after = l_paren;
+
+ const call_expr = CallExpr.init(p, lhs.node, func.node);
+
+ while (p.eatToken(.r_paren) == null) {
+ const param_tok = p.tok_i;
+ if (arg_count == params.len) first_after = p.tok_i;
+ var arg = try p.assignExpr();
+ try arg.expect(p);
+
+ if (call_expr.shouldPerformLvalConversion(arg_count)) {
+ try arg.lvalConversion(p);
+ }
+ if (arg.ty.hasIncompleteSize() and !arg.ty.is(.void)) return error.ParsingFailed;
+
+ if (arg_count >= params.len) {
+ if (call_expr.shouldPromoteVarArg(arg_count)) {
+ if (arg.ty.isInt()) try arg.intCast(p, arg.ty.integerPromotion(p.comp), param_tok);
+ if (arg.ty.is(.float)) try arg.floatCast(p, .{ .specifier = .double });
+ }
+ try call_expr.checkVarArg(p, first_after, param_tok, &arg, arg_count);
+ try arg.saveValue(p);
+ try p.list_buf.append(arg.node);
+ arg_count += 1;
+
+ _ = p.eatToken(.comma) orelse {
+ try p.expectClosing(l_paren, .r_paren);
+ break;
+ };
+ continue;
+ }
+ const p_ty = params[arg_count].ty;
+ if (call_expr.shouldCoerceArg(arg_count)) {
+ try arg.coerce(p, p_ty, param_tok, .{ .arg = params[arg_count].name_tok });
+ }
+ try arg.saveValue(p);
+ try p.list_buf.append(arg.node);
+ arg_count += 1;
+
+ _ = p.eatToken(.comma) orelse {
+ try p.expectClosing(l_paren, .r_paren);
+ break;
+ };
+ }
+
+ const actual: u32 = @intCast(arg_count);
+ const extra = Diagnostics.Message.Extra{ .arguments = .{
+ .expected = @intCast(params.len),
+ .actual = actual,
+ } };
+ if (call_expr.paramCountOverride()) |expected| {
+ if (expected != actual) {
+ try p.errExtra(.expected_arguments, first_after, .{ .arguments = .{ .expected = expected, .actual = actual } });
+ }
+ } else if (ty.is(.func) and params.len != arg_count) {
+ try p.errExtra(.expected_arguments, first_after, extra);
+ } else if (ty.is(.old_style_func) and params.len != arg_count) {
+ try p.errExtra(.expected_arguments_old, first_after, extra);
+ } else if (ty.is(.var_args_func) and arg_count < params.len) {
+ try p.errExtra(.expected_at_least_arguments, first_after, extra);
+ }
+
+ return call_expr.finish(p, ty, list_buf_top, arg_count);
+}
+
+fn checkArrayBounds(p: *Parser, index: Result, array: Result, tok: TokenIndex) !void {
+ if (index.val.tag == .unavailable) return;
+
+ const array_len = array.ty.arrayLen() orelse return;
+ if (array_len == 0) return;
+
+ if (array_len == 1) {
+ if (p.getNode(array.node, .member_access_expr) orelse p.getNode(array.node, .member_access_ptr_expr)) |node| {
+ const data = p.nodes.items(.data)[@intFromEnum(node)];
+ var lhs = p.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
+ if (lhs.get(.pointer)) |ptr| {
+ lhs = ptr.data.sub_type.*;
+ }
+ if (lhs.is(.@"struct")) {
+ const record = lhs.getRecord().?;
+ if (data.member.index + 1 == record.fields.len) {
+ if (!index.val.isZero()) {
+ try p.errExtra(.old_style_flexible_struct, tok, .{
+ .unsigned = index.val.data.int,
+ });
+ }
+ return;
+ }
+ }
+ }
+ }
+ const len = Value.int(array_len);
+
+ if (index.ty.isUnsignedInt(p.comp)) {
+ if (index.val.compare(.gte, len, p.comp.types.size, p.comp))
+ try p.errExtra(.array_after, tok, .{ .unsigned = index.val.data.int });
+ } else {
+ if (index.val.compare(.lt, Value.int(0), index.ty, p.comp)) {
+ try p.errExtra(.array_before, tok, .{
+ .signed = index.val.signExtend(index.ty, p.comp),
+ });
+ } else if (index.val.compare(.gte, len, p.comp.types.size, p.comp)) {
+ try p.errExtra(.array_after, tok, .{ .unsigned = index.val.data.int });
+ }
+ }
+}
+
+/// primaryExpr
+/// : IDENTIFIER
+/// | keyword_true
+/// | keyword_false
+/// | keyword_nullptr
+/// | INTEGER_LITERAL
+/// | FLOAT_LITERAL
+/// | IMAGINARY_LITERAL
+/// | CHAR_LITERAL
+/// | STRING_LITERAL
+/// | '(' expr ')'
+/// | genericSelection
+fn primaryExpr(p: *Parser) Error!Result {
+ if (p.eatToken(.l_paren)) |l_paren| {
+ var e = try p.expr();
+ try e.expect(p);
+ try p.expectClosing(l_paren, .r_paren);
+ try e.un(p, .paren_expr);
+ return e;
+ }
+ switch (p.tok_ids[p.tok_i]) {
+ .identifier, .extended_identifier => {
+ const name_tok = p.expectIdentifier() catch unreachable;
+ const name = p.tokSlice(name_tok);
+ const interned_name = try p.comp.intern(name);
+ if (p.syms.findSymbol(interned_name)) |sym| {
+ try p.checkDeprecatedUnavailable(sym.ty, name_tok, sym.tok);
+ if (sym.kind == .constexpr) {
+ return Result{
+ .val = sym.val,
+ .ty = sym.ty,
+ .node = try p.addNode(.{
+ .tag = .decl_ref_expr,
+ .ty = sym.ty,
+ .data = .{ .decl_ref = name_tok },
+ }),
+ };
+ }
+ if (sym.val.tag == .int) {
+ switch (p.const_decl_folding) {
+ .gnu_folding_extension => try p.errTok(.const_decl_folded, name_tok),
+ .gnu_vla_folding_extension => try p.errTok(.const_decl_folded_vla, name_tok),
+ else => {},
+ }
+ }
+ return Result{
+ .val = if (p.const_decl_folding == .no_const_decl_folding and sym.kind != .enumeration) Value{} else sym.val,
+ .ty = sym.ty,
+ .node = try p.addNode(.{
+ .tag = if (sym.kind == .enumeration) .enumeration_ref else .decl_ref_expr,
+ .ty = sym.ty,
+ .data = .{ .decl_ref = name_tok },
+ }),
+ };
+ }
+ if (try p.comp.builtins.getOrCreate(p.comp, name, p.arena)) |some| {
+ for (p.tok_ids[p.tok_i..]) |id| switch (id) {
+ .r_paren => {}, // closing grouped expr
+ .l_paren => break, // beginning of a call
+ else => {
+ try p.errTok(.builtin_must_be_called, name_tok);
+ return error.ParsingFailed;
+ },
+ };
+ if (some.builtin.properties.header != .none) {
+ try p.errStr(.implicit_builtin, name_tok, name);
+ try p.errExtra(.implicit_builtin_header_note, name_tok, .{ .builtin_with_header = .{
+ .builtin = some.builtin.tag,
+ .header = some.builtin.properties.header,
+ } });
+ }
+
+ return Result{
+ .ty = some.ty,
+ .node = try p.addNode(.{
+ .tag = .builtin_call_expr_one,
+ .ty = some.ty,
+ .data = .{ .decl = .{ .name = name_tok, .node = .none } },
+ }),
+ };
+ }
+ if (p.tok_ids[p.tok_i] == .l_paren) {
+ // allow implicitly declaring functions before C99 like `puts("foo")`
+ if (mem.startsWith(u8, name, "__builtin_"))
+ try p.errStr(.unknown_builtin, name_tok, name)
+ else
+ try p.errStr(.implicit_func_decl, name_tok, name);
+
+ const func_ty = try p.arena.create(Type.Func);
+ func_ty.* = .{ .return_type = .{ .specifier = .int }, .params = &.{} };
+ const ty: Type = .{ .specifier = .old_style_func, .data = .{ .func = func_ty } };
+ const node = try p.addNode(.{
+ .ty = ty,
+ .tag = .fn_proto,
+ .data = .{ .decl = .{ .name = name_tok } },
+ });
+
+ try p.decl_buf.append(node);
+ try p.syms.declareSymbol(p, interned_name, ty, name_tok, node);
+
+ return Result{
+ .ty = ty,
+ .node = try p.addNode(.{
+ .tag = .decl_ref_expr,
+ .ty = ty,
+ .data = .{ .decl_ref = name_tok },
+ }),
+ };
+ }
+ try p.errStr(.undeclared_identifier, name_tok, p.tokSlice(name_tok));
+ return error.ParsingFailed;
+ },
+ .keyword_true, .keyword_false => |id| {
+ p.tok_i += 1;
+ const numeric_value = @intFromBool(id == .keyword_true);
+ const res = Result{
+ .val = Value.int(numeric_value),
+ .ty = .{ .specifier = .bool },
+ .node = try p.addNode(.{
+ .tag = .bool_literal,
+ .ty = .{ .specifier = .bool },
+ .data = .{ .int = numeric_value },
+ }),
+ };
+ std.debug.assert(!p.in_macro); // Should have been replaced with .one / .zero
+ try p.value_map.put(res.node, res.val);
+ return res;
+ },
+ .keyword_nullptr => {
+ defer p.tok_i += 1;
+ try p.errStr(.pre_c2x_compat, p.tok_i, "'nullptr'");
+ return Result{
+ .val = .{ .tag = .nullptr_t },
+ .ty = .{ .specifier = .nullptr_t },
+ .node = try p.addNode(.{
+ .tag = .nullptr_literal,
+ .ty = .{ .specifier = .nullptr_t },
+ .data = undefined,
+ }),
+ };
+ },
+ .macro_func, .macro_function => {
+ defer p.tok_i += 1;
+ var ty: Type = undefined;
+ var tok = p.tok_i;
+ if (p.func.ident) |some| {
+ ty = some.ty;
+ tok = p.nodes.items(.data)[@intFromEnum(some.node)].decl.name;
+ } else if (p.func.ty) |_| {
+ const start: u32 = @intCast(p.retained_strings.items.len);
+ try p.retained_strings.appendSlice(p.tokSlice(p.func.name));
+ try p.retained_strings.append(0);
+ const predef = try p.makePredefinedIdentifier(start);
+ ty = predef.ty;
+ p.func.ident = predef;
+ } else {
+ const start: u32 = @intCast(p.retained_strings.items.len);
+ try p.retained_strings.append(0);
+ const predef = try p.makePredefinedIdentifier(start);
+ ty = predef.ty;
+ p.func.ident = predef;
+ try p.decl_buf.append(predef.node);
+ }
+ if (p.func.ty == null) try p.err(.predefined_top_level);
+ return Result{
+ .ty = ty,
+ .node = try p.addNode(.{
+ .tag = .decl_ref_expr,
+ .ty = ty,
+ .data = .{ .decl_ref = tok },
+ }),
+ };
+ },
+ .macro_pretty_func => {
+ defer p.tok_i += 1;
+ var ty: Type = undefined;
+ if (p.func.pretty_ident) |some| {
+ ty = some.ty;
+ } else if (p.func.ty) |func_ty| {
+ const mapper = p.comp.string_interner.getSlowTypeMapper();
+ const start: u32 = @intCast(p.retained_strings.items.len);
+ try Type.printNamed(func_ty, p.tokSlice(p.func.name), mapper, p.comp.langopts, p.retained_strings.writer());
+ try p.retained_strings.append(0);
+ const predef = try p.makePredefinedIdentifier(start);
+ ty = predef.ty;
+ p.func.pretty_ident = predef;
+ } else {
+ const start: u32 = @intCast(p.retained_strings.items.len);
+ try p.retained_strings.appendSlice("top level\x00");
+ const predef = try p.makePredefinedIdentifier(start);
+ ty = predef.ty;
+ p.func.pretty_ident = predef;
+ try p.decl_buf.append(predef.node);
+ }
+ if (p.func.ty == null) try p.err(.predefined_top_level);
+ return Result{
+ .ty = ty,
+ .node = try p.addNode(.{
+ .tag = .decl_ref_expr,
+ .ty = ty,
+ .data = .{ .decl_ref = p.tok_i },
+ }),
+ };
+ },
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ => return p.stringLiteral(),
+ .char_literal,
+ .char_literal_utf_8,
+ .char_literal_utf_16,
+ .char_literal_utf_32,
+ .char_literal_wide,
+ => return p.charLiteral(),
+ .zero => {
+ p.tok_i += 1;
+ var res: Result = .{ .val = Value.int(0), .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
+ res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ return res;
+ },
+ .one => {
+ p.tok_i += 1;
+ var res: Result = .{ .val = Value.int(1), .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
+ res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ return res;
+ },
+ .pp_num => return p.ppNum(),
+ .embed_byte => {
+ assert(!p.in_macro);
+ const loc = p.pp.tokens.items(.loc)[p.tok_i];
+ p.tok_i += 1;
+ const buf = p.comp.getSource(.generated).buf[loc.byte_offset..];
+ var byte: u8 = buf[0] - '0';
+ for (buf[1..]) |c| {
+ if (!std.ascii.isDigit(c)) break;
+ byte *= 10;
+ byte += c - '0';
+ }
+ var res: Result = .{ .val = Value.int(byte) };
+ res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+ try p.value_map.put(res.node, res.val);
+ return res;
+ },
+ .keyword_generic => return p.genericSelection(),
+ else => return Result{},
+ }
+}
+
+fn makePredefinedIdentifier(p: *Parser, start: u32) !Result {
+ const end: u32 = @intCast(p.retained_strings.items.len);
+ const elem_ty = .{ .specifier = .char, .qual = .{ .@"const" = true } };
+ const arr_ty = try p.arena.create(Type.Array);
+ arr_ty.* = .{ .elem = elem_ty, .len = end - start };
+ const ty: Type = .{ .specifier = .array, .data = .{ .array = arr_ty } };
+
+ const val = Value.bytes(start, end);
+ const str_lit = try p.addNode(.{ .tag = .string_literal_expr, .ty = ty, .data = undefined });
+ if (!p.in_macro) try p.value_map.put(str_lit, val);
+
+ return Result{ .ty = ty, .node = try p.addNode(.{
+ .tag = .implicit_static_var,
+ .ty = ty,
+ .data = .{ .decl = .{ .name = p.tok_i, .node = str_lit } },
+ }) };
+}
+
+fn stringLiteral(p: *Parser) Error!Result {
+ var start = p.tok_i;
+ // use 1 for wchar_t
+ var width: ?u8 = null;
+ var is_u8_literal = false;
+ while (true) {
+ switch (p.tok_ids[p.tok_i]) {
+ .string_literal => {},
+ .string_literal_utf_16 => if (width) |some| {
+ if (some != 16) try p.err(.unsupported_str_cat);
+ } else {
+ width = 16;
+ },
+ .string_literal_utf_8 => {
+ is_u8_literal = true;
+ if (width) |some| {
+ if (some != 8) try p.err(.unsupported_str_cat);
+ } else {
+ width = 8;
+ }
+ },
+ .string_literal_utf_32 => if (width) |some| {
+ if (some != 32) try p.err(.unsupported_str_cat);
+ } else {
+ width = 32;
+ },
+ .string_literal_wide => if (width) |some| {
+ if (some != 1) try p.err(.unsupported_str_cat);
+ } else {
+ width = 1;
+ },
+ else => break,
+ }
+ p.tok_i += 1;
+ }
+ if (width == null) width = 8;
+ if (width.? != 8) return p.todo("unicode string literals");
+
+ const string_start = p.retained_strings.items.len;
+ while (start < p.tok_i) : (start += 1) {
+ var slice = p.tokSlice(start);
+ slice = slice[0 .. slice.len - 1];
+ var i = mem.indexOf(u8, slice, "\"").? + 1;
+ try p.retained_strings.ensureUnusedCapacity(slice.len);
+ while (i < slice.len) : (i += 1) {
+ switch (slice[i]) {
+ '\\' => {
+ i += 1;
+ switch (slice[i]) {
+ '\n' => i += 1,
+ '\r' => i += 2,
+ '\'', '\"', '\\', '?' => |c| p.retained_strings.appendAssumeCapacity(c),
+ 'n' => p.retained_strings.appendAssumeCapacity('\n'),
+ 'r' => p.retained_strings.appendAssumeCapacity('\r'),
+ 't' => p.retained_strings.appendAssumeCapacity('\t'),
+ 'a' => p.retained_strings.appendAssumeCapacity(0x07),
+ 'b' => p.retained_strings.appendAssumeCapacity(0x08),
+ 'e' => {
+ try p.errExtra(.non_standard_escape_char, start, .{ .unsigned = i - 1 });
+ p.retained_strings.appendAssumeCapacity(0x1B);
+ },
+ 'f' => p.retained_strings.appendAssumeCapacity(0x0C),
+ 'v' => p.retained_strings.appendAssumeCapacity(0x0B),
+ 'x' => p.retained_strings.appendAssumeCapacity(try p.parseNumberEscape(start, 16, slice, &i)),
+ '0'...'7' => p.retained_strings.appendAssumeCapacity(try p.parseNumberEscape(start, 8, slice, &i)),
+ 'u' => try p.parseUnicodeEscape(start, 4, slice, &i),
+ 'U' => try p.parseUnicodeEscape(start, 8, slice, &i),
+ else => unreachable,
+ }
+ },
+ else => |c| p.retained_strings.appendAssumeCapacity(c),
+ }
+ }
+ }
+ try p.retained_strings.append(0);
+ const slice = p.retained_strings.items[string_start..];
+
+ const arr_ty = try p.arena.create(Type.Array);
+ const specifier: Type.Specifier = if (is_u8_literal and p.comp.langopts.hasChar8_T()) .uchar else .char;
+
+ arr_ty.* = .{ .elem = .{ .specifier = specifier }, .len = slice.len };
+ var res: Result = .{
+ .ty = .{
+ .specifier = .array,
+ .data = .{ .array = arr_ty },
+ },
+ .val = Value.bytes(@intCast(string_start), @intCast(p.retained_strings.items.len)),
+ };
+ res.node = try p.addNode(.{ .tag = .string_literal_expr, .ty = res.ty, .data = undefined });
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ return res;
+}
+
+fn parseNumberEscape(p: *Parser, tok: TokenIndex, base: u8, slice: []const u8, i: *usize) !u8 {
+ if (base == 16) i.* += 1; // skip x
+ var char: u8 = 0;
+ var reported = false;
+ while (i.* < slice.len) : (i.* += 1) {
+ const val = std.fmt.charToDigit(slice[i.*], base) catch break; // validated by Tokenizer
+ const product, const overflowed = @mulWithOverflow(char, base);
+ if (overflowed != 0 and !reported) {
+ try p.errExtra(.escape_sequence_overflow, tok, .{ .unsigned = i.* });
+ reported = true;
+ }
+ char = product + val;
+ }
+ i.* -= 1;
+ return char;
+}
+
+fn parseUnicodeEscape(p: *Parser, tok: TokenIndex, count: u8, slice: []const u8, i: *usize) !void {
+ const c = std.fmt.parseInt(u21, slice[i.* + 1 ..][0..count], 16) catch 0x110000; // count validated by tokenizer
+ i.* += count + 1;
+ if (!std.unicode.utf8ValidCodepoint(c) or (c < 0xa0 and c != '$' and c != '@' and c != '`')) {
+ try p.errExtra(.invalid_universal_character, tok, .{ .unsigned = i.* - count - 2 });
+ return;
+ }
+ var buf: [4]u8 = undefined;
+ const to_write = std.unicode.utf8Encode(c, &buf) catch unreachable; // validated above
+ p.retained_strings.appendSliceAssumeCapacity(buf[0..to_write]);
+}
+
+fn charLiteral(p: *Parser) Error!Result {
+ defer p.tok_i += 1;
+ const allow_multibyte = switch (p.tok_ids[p.tok_i]) {
+ .char_literal => false,
+ .char_literal_utf_8 => false,
+ .char_literal_wide => true,
+ .char_literal_utf_16 => true,
+ .char_literal_utf_32 => true,
+ else => unreachable,
+ };
+ const ty: Type = switch (p.tok_ids[p.tok_i]) {
+ .char_literal => .{ .specifier = .int },
+ .char_literal_utf_8 => .{ .specifier = .uchar },
+ .char_literal_wide => p.comp.types.wchar,
+ .char_literal_utf_16 => .{ .specifier = .ushort },
+ .char_literal_utf_32 => .{ .specifier = .ulong },
+ else => unreachable,
+ };
+ const max: u32 = switch (p.tok_ids[p.tok_i]) {
+ .char_literal => std.math.maxInt(u8),
+ .char_literal_wide => @intCast(p.comp.types.wchar.maxInt(p.comp)),
+ .char_literal_utf_8 => std.math.maxInt(u8),
+ .char_literal_utf_16 => std.math.maxInt(u16),
+ .char_literal_utf_32 => std.math.maxInt(u32),
+ else => unreachable,
+ };
+ var multichar: u8 = switch (p.tok_ids[p.tok_i]) {
+ .char_literal => 0,
+ .char_literal_wide => 4,
+ .char_literal_utf_8 => 2,
+ .char_literal_utf_16 => 2,
+ .char_literal_utf_32 => 2,
+ else => unreachable,
+ };
+
+ var val: u32 = 0;
+ var overflow_reported = false;
+ var slice = p.tokSlice(p.tok_i);
+ slice = slice[0 .. slice.len - 1];
+ var i = mem.indexOf(u8, slice, "\'").? + 1;
+ while (i < slice.len) : (i += 1) {
+ var c: u32 = slice[i];
+ var multibyte = false;
+ switch (c) {
+ '\\' => {
+ i += 1;
+ switch (slice[i]) {
+ '\n' => i += 1,
+ '\r' => i += 2,
+ '\'', '\"', '\\', '?' => c = slice[i],
+ 'n' => c = '\n',
+ 'r' => c = '\r',
+ 't' => c = '\t',
+ 'a' => c = 0x07,
+ 'b' => c = 0x08,
+ 'e' => {
+ try p.errExtra(.non_standard_escape_char, p.tok_i, .{ .unsigned = i - 1 });
+ c = 0x1B;
+ },
+ 'f' => c = 0x0C,
+ 'v' => c = 0x0B,
+ 'x' => c = try p.parseNumberEscape(p.tok_i, 16, slice, &i),
+ '0'...'7' => c = try p.parseNumberEscape(p.tok_i, 8, slice, &i),
+ 'u', 'U' => return p.todo("unicode escapes in char literals"),
+ else => unreachable,
+ }
+ },
+ // These are safe since the source is checked to be valid utf8.
+ 0b1100_0000...0b1101_1111 => {
+ c &= 0b00011111;
+ c <<= 6;
+ c |= slice[i + 1] & 0b00111111;
+ i += 1;
+ multibyte = true;
+ },
+ 0b1110_0000...0b1110_1111 => {
+ c &= 0b00001111;
+ c <<= 6;
+ c |= slice[i + 1] & 0b00111111;
+ c <<= 6;
+ c |= slice[i + 2] & 0b00111111;
+ i += 2;
+ multibyte = true;
+ },
+ 0b1111_0000...0b1111_0111 => {
+ c &= 0b00000111;
+ c <<= 6;
+ c |= slice[i + 1] & 0b00111111;
+ c <<= 6;
+ c |= slice[i + 2] & 0b00111111;
+ c <<= 6;
+ c |= slice[i + 3] & 0b00111111;
+ i += 3;
+ multibyte = true;
+ },
+ else => {},
+ }
+ if (c > max or (multibyte and !allow_multibyte)) try p.err(.char_too_large);
+ switch (multichar) {
+ 0, 2, 4 => multichar += 1,
+ 1 => {
+ multichar = 99;
+ try p.err(.multichar_literal);
+ },
+ 3 => {
+ try p.err(.unicode_multichar_literal);
+ return error.ParsingFailed;
+ },
+ 5 => {
+ try p.err(.wide_multichar_literal);
+ val = 0;
+ multichar = 6;
+ },
+ 6 => val = 0,
+ else => {},
+ }
+ const product, const overflowed = @mulWithOverflow(val, max +% 1);
+ if (overflowed != 0 and !overflow_reported) {
+ try p.errExtra(.char_lit_too_wide, p.tok_i, .{ .unsigned = i });
+ overflow_reported = true;
+ }
+ val = product + c;
+ }
+
+ // This is the type the literal will have if we're in a macro; macros always operate on intmax_t/uintmax_t values
+ const macro_ty = if (ty.isUnsignedInt(p.comp) or (p.tok_ids[p.tok_i] == .char_literal and p.comp.getCharSignedness() == .unsigned))
+ p.comp.types.intmax.makeIntegerUnsigned()
+ else
+ p.comp.types.intmax;
+
+ var res = Result{
+ .ty = if (p.in_macro) macro_ty else ty,
+ .val = Value.int(val),
+ .node = try p.addNode(.{ .tag = .char_literal, .ty = ty, .data = undefined }),
+ };
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ return res;
+}
+
+fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
+ switch (suffix) {
+ .L => return p.todo("long double literals"),
+ .IL => {
+ try p.err(.gnu_imaginary_constant);
+ return p.todo("long double imaginary literals");
+ },
+ .None, .I, .F, .IF, .F16 => {
+ const ty = Type{ .specifier = switch (suffix) {
+ .None, .I => .double,
+ .F, .IF => .float,
+ .F16 => .float16,
+ else => unreachable,
+ } };
+ const d_val = std.fmt.parseFloat(f64, buf) catch |er| switch (er) {
+ error.InvalidCharacter => return p.todo("c2x digit separators in floats"),
+ else => unreachable,
+ };
+ const tag: Tree.Tag = switch (suffix) {
+ .None, .I => .double_literal,
+ .F, .IF => .float_literal,
+ .F16 => .float16_literal,
+ else => unreachable,
+ };
+ var res = Result{
+ .ty = ty,
+ .node = try p.addNode(.{ .tag = tag, .ty = ty, .data = undefined }),
+ .val = Value.float(d_val),
+ };
+ if (suffix.isImaginary()) {
+ try p.err(.gnu_imaginary_constant);
+ res.ty = .{ .specifier = switch (suffix) {
+ .I => .complex_double,
+ .IF => .complex_float,
+ else => unreachable,
+ } };
+ res.val.tag = .unavailable;
+ try res.un(p, .imaginary_literal);
+ }
+ return res;
+ },
+ else => unreachable,
+ }
+}
+
+fn getIntegerPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
+ if (buf[0] == '.') return "";
+
+ if (!prefix.digitAllowed(buf[0])) {
+ switch (prefix) {
+ .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
+ .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
+ .hex => try p.errStr(.invalid_int_suffix, tok_i, buf),
+ .decimal => unreachable,
+ }
+ return error.ParsingFailed;
+ }
+
+ for (buf, 0..) |c, idx| {
+ if (idx == 0) continue;
+ switch (c) {
+ '.' => return buf[0..idx],
+ 'p', 'P' => return if (prefix == .hex) buf[0..idx] else {
+ try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]);
+ return error.ParsingFailed;
+ },
+ 'e', 'E' => {
+ switch (prefix) {
+ .hex => continue,
+ .decimal => return buf[0..idx],
+ .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
+ .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
+ }
+ return error.ParsingFailed;
+ },
+ '0'...'9', 'a'...'d', 'A'...'D', 'f', 'F' => {
+ if (!prefix.digitAllowed(c)) {
+ switch (prefix) {
+ .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
+ .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
+ .decimal, .hex => try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]),
+ }
+ return error.ParsingFailed;
+ }
+ },
+ '\'' => {},
+ else => return buf[0..idx],
+ }
+ }
+ return buf;
+}
+
+fn fixedSizeInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
+ var val: u64 = 0;
+ var overflow = false;
+ for (buf) |c| {
+ const digit: u64 = switch (c) {
+ '0'...'9' => c - '0',
+ 'A'...'Z' => c - 'A' + 10,
+ 'a'...'z' => c - 'a' + 10,
+ '\'' => continue,
+ else => unreachable,
+ };
+
+ if (val != 0) {
+ const product, const overflowed = @mulWithOverflow(val, base);
+ if (overflowed != 0) {
+ overflow = true;
+ }
+ val = product;
+ }
+ const sum, const overflowed = @addWithOverflow(val, digit);
+ if (overflowed != 0) overflow = true;
+ val = sum;
+ }
+ if (overflow) {
+ try p.errTok(.int_literal_too_big, tok_i);
+ var res: Result = .{ .ty = .{ .specifier = .ulong_long }, .val = Value.int(val) };
+ res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ return res;
+ }
+ if (suffix.isSignedInteger()) {
+ if (val > p.comp.types.intmax.maxInt(p.comp)) {
+ try p.errTok(.implicitly_unsigned_literal, tok_i);
+ }
+ }
+ return if (base == 10)
+ switch (suffix) {
+ .None, .I => p.castInt(val, &.{ .int, .long, .long_long }),
+ .U, .IU => p.castInt(val, &.{ .uint, .ulong, .ulong_long }),
+ .L, .IL => p.castInt(val, &.{ .long, .long_long }),
+ .UL, .IUL => p.castInt(val, &.{ .ulong, .ulong_long }),
+ .LL, .ILL => p.castInt(val, &.{.long_long}),
+ .ULL, .IULL => p.castInt(val, &.{.ulong_long}),
+ else => unreachable,
+ }
+ else switch (suffix) {
+ .None, .I => p.castInt(val, &.{ .int, .uint, .long, .ulong, .long_long, .ulong_long }),
+ .U, .IU => p.castInt(val, &.{ .uint, .ulong, .ulong_long }),
+ .L, .IL => p.castInt(val, &.{ .long, .ulong, .long_long, .ulong_long }),
+ .UL, .IUL => p.castInt(val, &.{ .ulong, .ulong_long }),
+ .LL, .ILL => p.castInt(val, &.{ .long_long, .ulong_long }),
+ .ULL, .IULL => p.castInt(val, &.{.ulong_long}),
+ else => unreachable,
+ };
+}
+
+fn parseInt(p: *Parser, prefix: NumberPrefix, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
+ if (prefix == .binary) {
+ try p.errTok(.binary_integer_literal, tok_i);
+ }
+ const base = @intFromEnum(prefix);
+ var res = if (suffix.isBitInt())
+ try p.bitInt(base, buf, suffix, tok_i)
+ else
+ try p.fixedSizeInt(base, buf, suffix, tok_i);
+
+ if (suffix.isImaginary()) {
+ try p.errTok(.gnu_imaginary_constant, tok_i);
+ res.ty = res.ty.makeComplex();
+ res.val.tag = .unavailable;
+ try res.un(p, .imaginary_literal);
+ }
+ return res;
+}
+
+fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) Error!Result {
+ try p.errStr(.pre_c2x_compat, tok_i, "'_BitInt' suffix for literals");
+ try p.errTok(.bitint_suffix, tok_i);
+
+ var managed = try big.int.Managed.init(p.comp.gpa);
+ defer managed.deinit();
+
+ managed.setString(base, buf) catch |e| switch (e) {
+ error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16
+ error.InvalidCharacter => unreachable, // digits validated by Tokenizer
+ else => |er| return er,
+ };
+ const c = managed.toConst();
+ const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: {
+ // Literal `0` requires at least 1 bit
+ const count = @max(1, c.bitCountTwosComp());
+ // The wb suffix results in a _BitInt that includes space for the sign bit even if the
+ // value of the constant is positive or was specified in hexadecimal or octal notation.
+ const sign_bits = @intFromBool(suffix.isSignedInteger());
+ const bits_needed = count + sign_bits;
+ if (bits_needed > Compilation.bit_int_max_bits) {
+ const specifier: Type.Builder.Specifier = switch (suffix) {
+ .WB => .{ .bit_int = 0 },
+ .UWB => .{ .ubit_int = 0 },
+ .IWB => .{ .complex_bit_int = 0 },
+ .IUWB => .{ .complex_ubit_int = 0 },
+ else => unreachable,
+ };
+ try p.errStr(.bit_int_too_big, tok_i, specifier.str(p.comp.langopts).?);
+ return error.ParsingFailed;
+ }
+ if (bits_needed > 64) {
+ return p.todo("_BitInt constants > 64 bits");
+ }
+ break :blk @intCast(bits_needed);
+ };
+
+ const val = c.to(u64) catch |e| switch (e) {
+ error.NegativeIntoUnsigned => unreachable, // unary minus parsed elsewhere; we only see positive integers
+ error.TargetTooSmall => unreachable, // Validated above but Todo: handle larger _BitInt
+ };
+
+ var res: Result = .{
+ .val = Value.int(val),
+ .ty = .{
+ .specifier = .bit_int,
+ .data = .{ .int = .{ .bits = bits_needed, .signedness = suffix.signedness() } },
+ },
+ };
+ res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = .{ .int = val } });
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ return res;
+}
+
+fn getFracPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
+ if (buf.len == 0 or buf[0] != '.') return "";
+ assert(prefix != .octal);
+ if (prefix == .binary) {
+ try p.errStr(.invalid_int_suffix, tok_i, buf);
+ return error.ParsingFailed;
+ }
+ for (buf, 0..) |c, idx| {
+ if (idx == 0) continue;
+ if (c == '\'') continue;
+ if (!prefix.digitAllowed(c)) return buf[0..idx];
+ }
+ return buf;
+}
+
+fn getExponent(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
+ if (buf.len == 0) return "";
+
+ switch (buf[0]) {
+ 'e', 'E' => assert(prefix == .decimal),
+ 'p', 'P' => if (prefix != .hex) {
+ try p.errStr(.invalid_float_suffix, tok_i, buf);
+ return error.ParsingFailed;
+ },
+ else => return "",
+ }
+ const end = for (buf, 0..) |c, idx| {
+ if (idx == 0) continue;
+ if (idx == 1 and (c == '+' or c == '-')) continue;
+ switch (c) {
+ '0'...'9' => {},
+ '\'' => continue,
+ else => break idx,
+ }
+ } else buf.len;
+ const exponent = buf[0..end];
+ if (std.mem.indexOfAny(u8, exponent, "0123456789") == null) {
+ try p.errTok(.exponent_has_no_digits, tok_i);
+ return error.ParsingFailed;
+ }
+ return exponent;
+}
+
+/// Using an explicit `tok_i` parameter instead of `p.tok_i` makes it easier
+/// to parse numbers in pragma handlers.
+pub fn parseNumberToken(p: *Parser, tok_i: TokenIndex) !Result {
+ const buf = p.tokSlice(tok_i);
+ const prefix = NumberPrefix.fromString(buf);
+ const after_prefix = buf[prefix.stringLen()..];
+
+ const int_part = try p.getIntegerPart(after_prefix, prefix, tok_i);
+
+ const after_int = after_prefix[int_part.len..];
+
+ const frac = try p.getFracPart(after_int, prefix, tok_i);
+ const after_frac = after_int[frac.len..];
+
+ const exponent = try p.getExponent(after_frac, prefix, tok_i);
+ const suffix_str = after_frac[exponent.len..];
+ const is_float = (exponent.len > 0 or frac.len > 0);
+ const suffix = NumberSuffix.fromString(suffix_str, if (is_float) .float else .int) orelse {
+ if (is_float) {
+ try p.errStr(.invalid_float_suffix, tok_i, suffix_str);
+ } else {
+ try p.errStr(.invalid_int_suffix, tok_i, suffix_str);
+ }
+ return error.ParsingFailed;
+ };
+
+ if (is_float) {
+ assert(prefix == .hex or prefix == .decimal);
+ if (prefix == .hex and exponent.len == 0) {
+ try p.errTok(.hex_floating_constant_requires_exponent, tok_i);
+ return error.ParsingFailed;
+ }
+ const number = buf[0 .. buf.len - suffix_str.len];
+ return p.parseFloat(number, suffix);
+ } else {
+ return p.parseInt(prefix, int_part, suffix, tok_i);
+ }
+}
+
+fn ppNum(p: *Parser) Error!Result {
+ defer p.tok_i += 1;
+ var res = try p.parseNumberToken(p.tok_i);
+ if (p.in_macro) {
+ if (res.ty.isFloat() or !res.ty.isReal()) {
+ try p.errTok(.float_literal_in_pp_expr, p.tok_i);
+ return error.ParsingFailed;
+ }
+ res.ty = if (res.ty.isUnsignedInt(p.comp)) p.comp.types.intmax.makeIntegerUnsigned() else p.comp.types.intmax;
+ } else {
+ try p.value_map.put(res.node, res.val);
+ }
+ return res;
+}
+
+fn castInt(p: *Parser, val: u64, specs: []const Type.Specifier) Error!Result {
+ var res: Result = .{ .val = Value.int(val) };
+ for (specs) |spec| {
+ const ty = Type{ .specifier = spec };
+ const unsigned = ty.isUnsignedInt(p.comp);
+ const size = ty.sizeof(p.comp).?;
+ res.ty = ty;
+
+ if (unsigned) {
+ switch (size) {
+ 2 => if (val <= std.math.maxInt(u16)) break,
+ 4 => if (val <= std.math.maxInt(u32)) break,
+ 8 => if (val <= std.math.maxInt(u64)) break,
+ else => unreachable,
+ }
+ } else {
+ switch (size) {
+ 2 => if (val <= std.math.maxInt(i16)) break,
+ 4 => if (val <= std.math.maxInt(i32)) break,
+ 8 => if (val <= std.math.maxInt(i64)) break,
+ else => unreachable,
+ }
+ }
+ } else {
+ res.ty = .{ .specifier = .ulong_long };
+ }
+ res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = .{ .int = val } });
+ if (!p.in_macro) try p.value_map.put(res.node, res.val);
+ return res;
+}
+
+/// Run a parser function but do not evaluate the result
+fn parseNoEval(p: *Parser, comptime func: fn (*Parser) Error!Result) Error!Result {
+ const no_eval = p.no_eval;
+ defer p.no_eval = no_eval;
+ p.no_eval = true;
+ const parsed = try func(p);
+ try parsed.expect(p);
+ return parsed;
+}
+
+/// genericSelection : keyword_generic '(' assignExpr ',' genericAssoc (',' genericAssoc)* ')'
+/// genericAssoc
+/// : typeName ':' assignExpr
+/// | keyword_default ':' assignExpr
+fn genericSelection(p: *Parser) Error!Result {
+ p.tok_i += 1;
+ const l_paren = try p.expectToken(.l_paren);
+ const controlling_tok = p.tok_i;
+ const controlling = try p.parseNoEval(assignExpr);
+ _ = try p.expectToken(.comma);
+ var controlling_ty = controlling.ty;
+ if (controlling_ty.isArray()) controlling_ty.decayArray();
+
+ const list_buf_top = p.list_buf.items.len;
+ defer p.list_buf.items.len = list_buf_top;
+ try p.list_buf.append(controlling.node);
+
+ // Use decl_buf to store the token indexes of previous cases
+ const decl_buf_top = p.decl_buf.items.len;
+ defer p.decl_buf.items.len = decl_buf_top;
+
+ var default_tok: ?TokenIndex = null;
+ var default: Result = undefined;
+ var chosen_tok: TokenIndex = undefined;
+ var chosen: Result = .{};
+ while (true) {
+ const start = p.tok_i;
+ if (try p.typeName()) |ty| blk: {
+ if (ty.isArray()) {
+ try p.errTok(.generic_array_type, start);
+ } else if (ty.isFunc()) {
+ try p.errTok(.generic_func_type, start);
+ } else if (ty.anyQual()) {
+ try p.errTok(.generic_qual_type, start);
+ }
+ _ = try p.expectToken(.colon);
+ const node = try p.assignExpr();
+ try node.expect(p);
+
+ if (ty.eql(controlling_ty, p.comp, false)) {
+ if (chosen.node == .none) {
+ chosen = node;
+ chosen_tok = start;
+ break :blk;
+ }
+ try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
+ try p.errStr(.generic_duplicate_here, chosen_tok, try p.typeStr(ty));
+ }
+ for (p.list_buf.items[list_buf_top + 1 ..], p.decl_buf.items[decl_buf_top..]) |item, prev_tok| {
+ const prev_ty = p.nodes.items(.ty)[@intFromEnum(item)];
+ if (prev_ty.eql(ty, p.comp, true)) {
+ try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
+ try p.errStr(.generic_duplicate_here, @intFromEnum(prev_tok), try p.typeStr(ty));
+ }
+ }
+ try p.list_buf.append(try p.addNode(.{
+ .tag = .generic_association_expr,
+ .ty = ty,
+ .data = .{ .un = node.node },
+ }));
+ try p.decl_buf.append(@enumFromInt(start));
+ } else if (p.eatToken(.keyword_default)) |tok| {
+ if (default_tok) |prev| {
+ try p.errTok(.generic_duplicate_default, tok);
+ try p.errTok(.previous_case, prev);
+ }
+ default_tok = tok;
+ _ = try p.expectToken(.colon);
+ default = try p.assignExpr();
+ try default.expect(p);
+ } else {
+ if (p.list_buf.items.len == list_buf_top + 1) {
+ try p.err(.expected_type);
+ return error.ParsingFailed;
+ }
+ break;
+ }
+ if (p.eatToken(.comma) == null) break;
+ }
+ try p.expectClosing(l_paren, .r_paren);
+
+ if (chosen.node == .none) {
+ if (default_tok != null) {
+ try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
+ .tag = .generic_default_expr,
+ .data = .{ .un = default.node },
+ }));
+ chosen = default;
+ } else {
+ try p.errStr(.generic_no_match, controlling_tok, try p.typeStr(controlling_ty));
+ return error.ParsingFailed;
+ }
+ } else {
+ try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
+ .tag = .generic_association_expr,
+ .data = .{ .un = chosen.node },
+ }));
+ if (default_tok != null) {
+ try p.list_buf.append(try p.addNode(.{
+ .tag = .generic_default_expr,
+ .data = .{ .un = chosen.node },
+ }));
+ }
+ }
+
+ var generic_node: Tree.Node = .{
+ .tag = .generic_expr_one,
+ .ty = chosen.ty,
+ .data = .{ .bin = .{ .lhs = controlling.node, .rhs = chosen.node } },
+ };
+ const associations = p.list_buf.items[list_buf_top..];
+ if (associations.len > 2) { // associations[0] == controlling.node
+ generic_node.tag = .generic_expr;
+ generic_node.data = .{ .range = try p.addList(associations) };
+ }
+ chosen.node = try p.addNode(generic_node);
+ return chosen;
+}
deps/aro/Pragma.zig
@@ -0,0 +1,83 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Preprocessor = @import("Preprocessor.zig");
+const Parser = @import("Parser.zig");
+const TokenIndex = @import("Tree.zig").TokenIndex;
+
+const Pragma = @This();
+
+pub const Error = Compilation.Error || error{ UnknownPragma, StopPreprocessing };
+
+/// Called during Preprocessor.init
+beforePreprocess: ?*const fn (*Pragma, *Compilation) void = null,
+
+/// Called at the beginning of Parser.parse
+beforeParse: ?*const fn (*Pragma, *Compilation) void = null,
+
+/// Called at the end of Parser.parse if a Tree was successfully parsed
+afterParse: ?*const fn (*Pragma, *Compilation) void = null,
+
+/// Called during Compilation.deinit
+deinit: *const fn (*Pragma, *Compilation) void,
+
+/// Called whenever the preprocessor encounters this pragma. `start_idx` is the index
+/// within `pp.tokens` of the pragma name token. The pragma end is indicated by a
+/// .nl token (which may be generated if the source ends with a pragma with no newline)
+/// As an example, given the following line:
+/// #pragma GCC diagnostic error "-Wnewline-eof" \n
+/// Then pp.tokens.get(start_idx) will return the `GCC` token.
+/// Return error.UnknownPragma to emit an `unknown_pragma` diagnostic
+/// Return error.StopPreprocessing to stop preprocessing the current file (see once.zig)
+preprocessorHandler: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) Error!void = null,
+
+/// Called during token pretty-printing (`-E` option). If this returns true, the pragma will
+/// be printed; otherwise it will be omitted. start_idx is the index of the pragma name token
+preserveTokens: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) bool = null,
+
+/// Same as preprocessorHandler except called during parsing
+/// The parser's `p.tok_i` field must not be changed
+parserHandler: ?*const fn (*Pragma, *Parser, start_idx: TokenIndex) Compilation.Error!void = null,
+
+pub fn pasteTokens(pp: *Preprocessor, start_idx: TokenIndex) ![]const u8 {
+ if (pp.tokens.get(start_idx).id == .nl) return error.ExpectedStringLiteral;
+
+ const char_top = pp.char_buf.items.len;
+ defer pp.char_buf.items.len = char_top;
+ var i: usize = 0;
+ var lparen_count: u32 = 0;
+ var rparen_count: u32 = 0;
+ while (true) : (i += 1) {
+ const tok = pp.tokens.get(start_idx + i);
+ if (tok.id == .nl) break;
+ switch (tok.id) {
+ .l_paren => {
+ if (lparen_count != i) return error.ExpectedStringLiteral;
+ lparen_count += 1;
+ },
+ .r_paren => rparen_count += 1,
+ .string_literal => {
+ if (rparen_count != 0) return error.ExpectedStringLiteral;
+ const str = pp.expandedSlice(tok);
+ try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
+ },
+ else => return error.ExpectedStringLiteral,
+ }
+ }
+ if (lparen_count != rparen_count) return error.ExpectedStringLiteral;
+ return pp.char_buf.items[char_top..];
+}
+
+pub fn shouldPreserveTokens(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
+ if (self.preserveTokens) |func| return func(self, pp, start_idx);
+ return false;
+}
+
+pub fn preprocessorCB(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Error!void {
+ if (self.preprocessorHandler) |func| return func(self, pp, start_idx);
+}
+
+pub fn parserCB(self: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
+ const tok_index = p.tok_i;
+ defer std.debug.assert(tok_index == p.tok_i);
+ if (self.parserHandler) |func| return func(self, p, start_idx);
+}
deps/aro/Preprocessor.zig
@@ -0,0 +1,2691 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const assert = std.debug.assert;
+const Compilation = @import("Compilation.zig");
+const Error = Compilation.Error;
+const Source = @import("Source.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const RawToken = Tokenizer.Token;
+const Parser = @import("Parser.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const Token = @import("Tree.zig").Token;
+const Attribute = @import("Attribute.zig");
+const features = @import("features.zig");
+
+const Preprocessor = @This();
+const DefineMap = std.StringHashMap(Macro);
+const RawTokenList = std.ArrayList(RawToken);
+const max_include_depth = 200;
+
+/// Errors that can be returned when expanding a macro.
+/// error.UnknownPragma can occur within Preprocessor.pragma() but
+/// it is handled there and doesn't escape that function
+const MacroError = Error || error{StopPreprocessing};
+
+const Macro = struct {
+ /// Parameters of the function type macro
+ params: []const []const u8,
+
+ /// Token constituting the macro body
+ tokens: []const RawToken,
+
+ /// If the function type macro has variable number of arguments
+ var_args: bool,
+
+ /// Is a function type macro
+ is_func: bool,
+
+ /// Is a predefined macro
+ is_builtin: bool = false,
+
+ /// Location of macro in the source
+ /// `byte_offset` and `line` are used to define the range of tokens included
+ /// in the macro.
+ loc: Source.Location,
+
+ fn eql(a: Macro, b: Macro, pp: *Preprocessor) bool {
+ if (a.tokens.len != b.tokens.len) return false;
+ if (a.is_builtin != b.is_builtin) return false;
+ for (a.tokens, b.tokens) |a_tok, b_tok| if (!tokEql(pp, a_tok, b_tok)) return false;
+
+ if (a.is_func and b.is_func) {
+ if (a.var_args != b.var_args) return false;
+ if (a.params.len != b.params.len) return false;
+ for (a.params, b.params) |a_param, b_param| if (!mem.eql(u8, a_param, b_param)) return false;
+ }
+
+ return true;
+ }
+
+ fn tokEql(pp: *Preprocessor, a: RawToken, b: RawToken) bool {
+ return mem.eql(u8, pp.tokSlice(a), pp.tokSlice(b));
+ }
+};
+
+comp: *Compilation,
+gpa: mem.Allocator,
+arena: std.heap.ArenaAllocator,
+defines: DefineMap,
+tokens: Token.List = .{},
+token_buf: RawTokenList,
+char_buf: std.ArrayList(u8),
+/// Counter that is incremented each time preprocess() is called
+/// Can be used to distinguish multiple preprocessings of the same file
+preprocess_count: u32 = 0,
+generated_line: u32 = 1,
+add_expansion_nl: u32 = 0,
+include_depth: u8 = 0,
+counter: u32 = 0,
+expansion_source_loc: Source.Location = undefined,
+poisoned_identifiers: std.StringHashMap(void),
+/// Map from Source.Id to macro name in the `#ifndef` condition which guards the source, if any
+include_guards: std.AutoHashMapUnmanaged(Source.Id, []const u8) = .{},
+
+/// Memory is retained to avoid allocation on every single token.
+top_expansion_buf: ExpandBuf,
+
+/// Dump current state to stderr.
+verbose: bool = false,
+preserve_whitespace: bool = false,
+
+pub fn init(comp: *Compilation) Preprocessor {
+ const pp = Preprocessor{
+ .comp = comp,
+ .gpa = comp.gpa,
+ .arena = std.heap.ArenaAllocator.init(comp.gpa),
+ .defines = DefineMap.init(comp.gpa),
+ .token_buf = RawTokenList.init(comp.gpa),
+ .char_buf = std.ArrayList(u8).init(comp.gpa),
+ .poisoned_identifiers = std.StringHashMap(void).init(comp.gpa),
+ .top_expansion_buf = ExpandBuf.init(comp.gpa),
+ };
+ comp.pragmaEvent(.before_preprocess);
+ return pp;
+}
+
+const builtin_macros = struct {
+ const args = [1][]const u8{"X"};
+
+ const has_attribute = [1]RawToken{.{
+ .id = .macro_param_has_attribute,
+ .source = .generated,
+ }};
+ const has_warning = [1]RawToken{.{
+ .id = .macro_param_has_warning,
+ .source = .generated,
+ }};
+ const has_feature = [1]RawToken{.{
+ .id = .macro_param_has_feature,
+ .source = .generated,
+ }};
+ const has_extension = [1]RawToken{.{
+ .id = .macro_param_has_extension,
+ .source = .generated,
+ }};
+ const has_builtin = [1]RawToken{.{
+ .id = .macro_param_has_builtin,
+ .source = .generated,
+ }};
+ const has_include = [1]RawToken{.{
+ .id = .macro_param_has_include,
+ .source = .generated,
+ }};
+ const has_include_next = [1]RawToken{.{
+ .id = .macro_param_has_include_next,
+ .source = .generated,
+ }};
+
+ const is_identifier = [1]RawToken{.{
+ .id = .macro_param_is_identifier,
+ .source = .generated,
+ }};
+
+ const pragma_operator = [1]RawToken{.{
+ .id = .macro_param_pragma_operator,
+ .source = .generated,
+ }};
+
+ const file = [1]RawToken{.{
+ .id = .macro_file,
+ .source = .generated,
+ }};
+ const line = [1]RawToken{.{
+ .id = .macro_line,
+ .source = .generated,
+ }};
+ const counter = [1]RawToken{.{
+ .id = .macro_counter,
+ .source = .generated,
+ }};
+};
+
+fn addBuiltinMacro(pp: *Preprocessor, name: []const u8, is_func: bool, tokens: []const RawToken) !void {
+ try pp.defines.putNoClobber(name, .{
+ .params = &builtin_macros.args,
+ .tokens = tokens,
+ .var_args = false,
+ .is_func = is_func,
+ .loc = .{ .id = .generated },
+ .is_builtin = true,
+ });
+}
+
+pub fn addBuiltinMacros(pp: *Preprocessor) !void {
+ try pp.addBuiltinMacro("__has_attribute", true, &builtin_macros.has_attribute);
+ try pp.addBuiltinMacro("__has_warning", true, &builtin_macros.has_warning);
+ try pp.addBuiltinMacro("__has_feature", true, &builtin_macros.has_feature);
+ try pp.addBuiltinMacro("__has_extension", true, &builtin_macros.has_extension);
+ try pp.addBuiltinMacro("__has_builtin", true, &builtin_macros.has_builtin);
+ try pp.addBuiltinMacro("__has_include", true, &builtin_macros.has_include);
+ try pp.addBuiltinMacro("__has_include_next", true, &builtin_macros.has_include_next);
+ try pp.addBuiltinMacro("__is_identifier", true, &builtin_macros.is_identifier);
+ try pp.addBuiltinMacro("_Pragma", true, &builtin_macros.pragma_operator);
+
+ try pp.addBuiltinMacro("__FILE__", false, &builtin_macros.file);
+ try pp.addBuiltinMacro("__LINE__", false, &builtin_macros.line);
+ try pp.addBuiltinMacro("__COUNTER__", false, &builtin_macros.counter);
+}
+
+pub fn deinit(pp: *Preprocessor) void {
+ pp.defines.deinit();
+ for (pp.tokens.items(.expansion_locs)) |loc| Token.free(loc, pp.gpa);
+ pp.tokens.deinit(pp.gpa);
+ pp.arena.deinit();
+ pp.token_buf.deinit();
+ pp.char_buf.deinit();
+ pp.poisoned_identifiers.deinit();
+ pp.include_guards.deinit(pp.gpa);
+ pp.top_expansion_buf.deinit();
+}
+
+/// Preprocess a source file, returns eof token.
+pub fn preprocess(pp: *Preprocessor, source: Source) Error!Token {
+ return pp.preprocessExtra(source) catch |er| switch (er) {
+ // This cannot occur in the main file and is handled in `include`.
+ error.StopPreprocessing => unreachable,
+ else => |e| return e,
+ };
+}
+
+/// Return the name of the #ifndef guard macro that starts a source, if any.
+fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 {
+ var tokenizer = Tokenizer{
+ .buf = source.buf,
+ .comp = pp.comp,
+ .source = source.id,
+ };
+ var hash = tokenizer.nextNoWS();
+ while (hash.id == .nl) hash = tokenizer.nextNoWS();
+ if (hash.id != .hash) return null;
+ const ifndef = tokenizer.nextNoWS();
+ if (ifndef.id != .keyword_ifndef) return null;
+ const guard = tokenizer.nextNoWS();
+ if (guard.id != .identifier) return null;
+ return pp.tokSlice(guard);
+}
+
+fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token {
+ if (pp.comp.invalid_utf8_locs.get(source.id)) |offset| {
+ try pp.comp.diag.add(.{
+ .tag = .invalid_utf8,
+ // Todo: compute line number
+ .loc = .{ .id = source.id, .byte_offset = offset },
+ }, &.{});
+ return error.FatalError;
+ }
+ var guard_name = pp.findIncludeGuard(source);
+
+ pp.preprocess_count += 1;
+ var tokenizer = Tokenizer{
+ .buf = source.buf,
+ .comp = pp.comp,
+ .source = source.id,
+ };
+
+ // Estimate how many new tokens this source will contain.
+ const estimated_token_count = source.buf.len / 8;
+ try pp.tokens.ensureTotalCapacity(pp.gpa, pp.tokens.len + estimated_token_count);
+
+ var if_level: u8 = 0;
+ var if_kind = std.PackedIntArray(u2, 256).init([1]u2{0} ** 256);
+ const until_else = 0;
+ const until_endif = 1;
+ const until_endif_seen_else = 2;
+
+ var start_of_line = true;
+ while (true) {
+ var tok = tokenizer.next();
+ switch (tok.id) {
+ .hash => if (!start_of_line) try pp.tokens.append(pp.gpa, tokFromRaw(tok)) else {
+ const directive = tokenizer.nextNoWS();
+ switch (directive.id) {
+ .keyword_error, .keyword_warning => {
+ // #error tokens..
+ pp.top_expansion_buf.items.len = 0;
+ const char_top = pp.char_buf.items.len;
+ defer pp.char_buf.items.len = char_top;
+
+ while (true) {
+ tok = tokenizer.next();
+ if (tok.id == .nl or tok.id == .eof) break;
+ if (tok.id == .whitespace) tok.id = .macro_ws;
+ try pp.top_expansion_buf.append(tokFromRaw(tok));
+ }
+ try pp.stringify(pp.top_expansion_buf.items);
+ const slice = pp.char_buf.items[char_top + 1 .. pp.char_buf.items.len - 2];
+ const duped = try pp.comp.diag.arena.allocator().dupe(u8, slice);
+
+ try pp.comp.diag.add(.{
+ .tag = if (directive.id == .keyword_error) .error_directive else .warning_directive,
+ .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
+ .extra = .{ .str = duped },
+ }, &.{});
+ },
+ .keyword_if => {
+ const sum, const overflowed = @addWithOverflow(if_level, 1);
+ if (overflowed != 0)
+ return pp.fatal(directive, "too many #if nestings", .{});
+ if_level = sum;
+
+ if (try pp.expr(&tokenizer)) {
+ if_kind.set(if_level, until_endif);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering then branch of #if", .{});
+ }
+ } else {
+ if_kind.set(if_level, until_else);
+ try pp.skip(&tokenizer, .until_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering else branch of #if", .{});
+ }
+ }
+ },
+ .keyword_ifdef => {
+ const sum, const overflowed = @addWithOverflow(if_level, 1);
+ if (overflowed != 0)
+ return pp.fatal(directive, "too many #if nestings", .{});
+ if_level = sum;
+
+ const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
+ try pp.expectNl(&tokenizer);
+ if (pp.defines.get(macro_name) != null) {
+ if_kind.set(if_level, until_endif);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering then branch of #ifdef", .{});
+ }
+ } else {
+ if_kind.set(if_level, until_else);
+ try pp.skip(&tokenizer, .until_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering else branch of #ifdef", .{});
+ }
+ }
+ },
+ .keyword_ifndef => {
+ const sum, const overflowed = @addWithOverflow(if_level, 1);
+ if (overflowed != 0)
+ return pp.fatal(directive, "too many #if nestings", .{});
+ if_level = sum;
+
+ const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
+ try pp.expectNl(&tokenizer);
+ if (pp.defines.get(macro_name) == null) {
+ if_kind.set(if_level, until_endif);
+ } else {
+ if_kind.set(if_level, until_else);
+ try pp.skip(&tokenizer, .until_else);
+ }
+ },
+ .keyword_elif => {
+ if (if_level == 0) {
+ try pp.err(directive, .elif_without_if);
+ if_level += 1;
+ if_kind.set(if_level, until_else);
+ } else if (if_level == 1) {
+ guard_name = null;
+ }
+ switch (if_kind.get(if_level)) {
+ until_else => if (try pp.expr(&tokenizer)) {
+ if_kind.set(if_level, until_endif);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering then branch of #elif", .{});
+ }
+ } else {
+ try pp.skip(&tokenizer, .until_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering else branch of #elif", .{});
+ }
+ },
+ until_endif => try pp.skip(&tokenizer, .until_endif),
+ until_endif_seen_else => {
+ try pp.err(directive, .elif_after_else);
+ skipToNl(&tokenizer);
+ },
+ else => unreachable,
+ }
+ },
+ .keyword_elifdef => {
+ if (if_level == 0) {
+ try pp.err(directive, .elifdef_without_if);
+ if_level += 1;
+ if_kind.set(if_level, until_else);
+ } else if (if_level == 1) {
+ guard_name = null;
+ }
+ switch (if_kind.get(if_level)) {
+ until_else => {
+ const macro_name = try pp.expectMacroName(&tokenizer);
+ if (macro_name == null) {
+ if_kind.set(if_level, until_else);
+ try pp.skip(&tokenizer, .until_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering else branch of #elifdef", .{});
+ }
+ } else {
+ try pp.expectNl(&tokenizer);
+ if (pp.defines.get(macro_name.?) != null) {
+ if_kind.set(if_level, until_endif);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering then branch of #elifdef", .{});
+ }
+ } else {
+ if_kind.set(if_level, until_else);
+ try pp.skip(&tokenizer, .until_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering else branch of #elifdef", .{});
+ }
+ }
+ }
+ },
+ until_endif => try pp.skip(&tokenizer, .until_endif),
+ until_endif_seen_else => {
+ try pp.err(directive, .elifdef_after_else);
+ skipToNl(&tokenizer);
+ },
+ else => unreachable,
+ }
+ },
+ .keyword_elifndef => {
+ if (if_level == 0) {
+ try pp.err(directive, .elifdef_without_if);
+ if_level += 1;
+ if_kind.set(if_level, until_else);
+ } else if (if_level == 1) {
+ guard_name = null;
+ }
+ switch (if_kind.get(if_level)) {
+ until_else => {
+ const macro_name = try pp.expectMacroName(&tokenizer);
+ if (macro_name == null) {
+ if_kind.set(if_level, until_else);
+ try pp.skip(&tokenizer, .until_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering else branch of #elifndef", .{});
+ }
+ } else {
+ try pp.expectNl(&tokenizer);
+ if (pp.defines.get(macro_name.?) == null) {
+ if_kind.set(if_level, until_endif);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering then branch of #elifndef", .{});
+ }
+ } else {
+ if_kind.set(if_level, until_else);
+ try pp.skip(&tokenizer, .until_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "entering else branch of #elifndef", .{});
+ }
+ }
+ }
+ },
+ until_endif => try pp.skip(&tokenizer, .until_endif),
+ until_endif_seen_else => {
+ try pp.err(directive, .elifdef_after_else);
+ skipToNl(&tokenizer);
+ },
+ else => unreachable,
+ }
+ },
+ .keyword_else => {
+ try pp.expectNl(&tokenizer);
+ if (if_level == 0) {
+ try pp.err(directive, .else_without_if);
+ continue;
+ } else if (if_level == 1) {
+ guard_name = null;
+ }
+ switch (if_kind.get(if_level)) {
+ until_else => {
+ if_kind.set(if_level, until_endif_seen_else);
+ if (pp.verbose) {
+ pp.verboseLog(directive, "#else branch here", .{});
+ }
+ },
+ until_endif => try pp.skip(&tokenizer, .until_endif_seen_else),
+ until_endif_seen_else => {
+ try pp.err(directive, .else_after_else);
+ skipToNl(&tokenizer);
+ },
+ else => unreachable,
+ }
+ },
+ .keyword_endif => {
+ try pp.expectNl(&tokenizer);
+ if (if_level == 0) {
+ guard_name = null;
+ try pp.err(directive, .endif_without_if);
+ continue;
+ } else if (if_level == 1) {
+ const saved_tokenizer = tokenizer;
+ defer tokenizer = saved_tokenizer;
+
+ var next = tokenizer.nextNoWS();
+ while (next.id == .nl) : (next = tokenizer.nextNoWS()) {}
+ if (next.id != .eof) guard_name = null;
+ }
+ if_level -= 1;
+ },
+ .keyword_define => try pp.define(&tokenizer),
+ .keyword_undef => {
+ const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
+
+ _ = pp.defines.remove(macro_name);
+ try pp.expectNl(&tokenizer);
+ },
+ .keyword_include => try pp.include(&tokenizer, .first),
+ .keyword_include_next => {
+ try pp.comp.diag.add(.{
+ .tag = .include_next,
+ .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
+ }, &.{});
+ if (pp.include_depth == 0) {
+ try pp.comp.diag.add(.{
+ .tag = .include_next_outside_header,
+ .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
+ }, &.{});
+ try pp.include(&tokenizer, .first);
+ } else {
+ try pp.include(&tokenizer, .next);
+ }
+ },
+ .keyword_embed => try pp.embed(&tokenizer),
+ .keyword_pragma => try pp.pragma(&tokenizer, directive, null, &.{}),
+ .keyword_line => {
+ // #line number "file"
+ const digits = tokenizer.nextNoWS();
+ if (digits.id != .pp_num) try pp.err(digits, .line_simple_digit);
+ // TODO: validate that the pp_num token is solely digits
+
+ if (digits.id == .eof or digits.id == .nl) continue;
+ const name = tokenizer.nextNoWS();
+ if (name.id == .eof or name.id == .nl) continue;
+ if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
+ try pp.expectNl(&tokenizer);
+ },
+ .pp_num => {
+ // # number "file" flags
+ // TODO: validate that the pp_num token is solely digits
+ // if not, emit `GNU line marker directive requires a simple digit sequence`
+ const name = tokenizer.nextNoWS();
+ if (name.id == .eof or name.id == .nl) continue;
+ if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
+
+ const flag_1 = tokenizer.nextNoWS();
+ if (flag_1.id == .eof or flag_1.id == .nl) continue;
+ const flag_2 = tokenizer.nextNoWS();
+ if (flag_2.id == .eof or flag_2.id == .nl) continue;
+ const flag_3 = tokenizer.nextNoWS();
+ if (flag_3.id == .eof or flag_3.id == .nl) continue;
+ const flag_4 = tokenizer.nextNoWS();
+ if (flag_4.id == .eof or flag_4.id == .nl) continue;
+ try pp.expectNl(&tokenizer);
+ },
+ .nl => {},
+ .eof => {
+ if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
+ return tokFromRaw(directive);
+ },
+ else => {
+ try pp.err(tok, .invalid_preprocessing_directive);
+ skipToNl(&tokenizer);
+ },
+ }
+ },
+ .whitespace => if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok)),
+ .nl => {
+ start_of_line = true;
+ if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok));
+ },
+ .eof => {
+ if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
+ // The following check needs to occur here and not at the top of the function
+ // because a pragma may change the level during preprocessing
+ if (source.buf.len > 0 and source.buf[source.buf.len - 1] != '\n') {
+ try pp.err(tok, .newline_eof);
+ }
+ if (guard_name) |name| {
+ if (try pp.include_guards.fetchPut(pp.gpa, source.id, name)) |prev| {
+ assert(mem.eql(u8, name, prev.value));
+ }
+ }
+ return tokFromRaw(tok);
+ },
+ else => {
+ if (tok.id.isMacroIdentifier() and pp.poisoned_identifiers.get(pp.tokSlice(tok)) != null) {
+ try pp.err(tok, .poisoned_identifier);
+ }
+ // Add the token to the buffer doing any necessary expansions.
+ start_of_line = false;
+ try pp.expandMacro(&tokenizer, tok);
+ },
+ }
+ }
+}
+
+/// Get raw token source string.
+/// Returned slice is invalidated when comp.generated_buf is updated.
+pub fn tokSlice(pp: *Preprocessor, token: RawToken) []const u8 {
+ if (token.id.lexeme()) |some| return some;
+ const source = pp.comp.getSource(token.source);
+ return source.buf[token.start..token.end];
+}
+
+/// Convert a token from the Tokenizer into a token used by the parser.
+fn tokFromRaw(raw: RawToken) Token {
+ return .{
+ .id = raw.id,
+ .loc = .{
+ .id = raw.source,
+ .byte_offset = raw.start,
+ .line = raw.line,
+ },
+ };
+}
+
+fn err(pp: *Preprocessor, raw: RawToken, tag: Diagnostics.Tag) !void {
+ try pp.comp.diag.add(.{
+ .tag = tag,
+ .loc = .{
+ .id = raw.source,
+ .byte_offset = raw.start,
+ .line = raw.line,
+ },
+ }, &.{});
+}
+
+fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) Compilation.Error {
+ const source = pp.comp.getSource(raw.source);
+ const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start });
+ return pp.comp.diag.fatal(source.path, line_col.line, raw.line, line_col.col, fmt, args);
+}
+
+fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void {
+ const source = pp.comp.getSource(raw.source);
+ const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start });
+
+ const stderr = std.io.getStdErr().writer();
+ var buf_writer = std.io.bufferedWriter(stderr);
+ const writer = buf_writer.writer();
+ defer buf_writer.flush() catch {};
+ writer.print("{s}:{d}:{d}: ", .{ source.path, line_col.line_no, line_col.col }) catch return;
+ writer.print(fmt, args) catch return;
+ writer.writeByte('\n') catch return;
+ writer.writeAll(line_col.line) catch return;
+ writer.writeByte('\n') catch return;
+}
+
+/// Consume next token, error if it is not an identifier.
+fn expectMacroName(pp: *Preprocessor, tokenizer: *Tokenizer) Error!?[]const u8 {
+ const macro_name = tokenizer.nextNoWS();
+ if (!macro_name.id.isMacroIdentifier()) {
+ try pp.err(macro_name, .macro_name_missing);
+ skipToNl(tokenizer);
+ return null;
+ }
+ return pp.tokSlice(macro_name);
+}
+
+/// Skip until after a newline, error if extra tokens before it.
+fn expectNl(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
+ var sent_err = false;
+ while (true) {
+ const tok = tokenizer.next();
+ if (tok.id == .nl or tok.id == .eof) return;
+ if (tok.id == .whitespace) continue;
+ if (!sent_err) {
+ sent_err = true;
+ try pp.err(tok, .extra_tokens_directive_end);
+ }
+ }
+}
+
+/// Consume all tokens until a newline and parse the result into a boolean.
+fn expr(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!bool {
+ const start = pp.tokens.len;
+ defer {
+ for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
+ pp.tokens.len = start;
+ }
+
+ pp.top_expansion_buf.items.len = 0;
+ const eof = while (true) {
+ var tok = tokenizer.next();
+ switch (tok.id) {
+ .nl, .eof => break tok,
+ .whitespace => if (pp.top_expansion_buf.items.len == 0) continue,
+ else => {},
+ }
+ try pp.top_expansion_buf.append(tokFromRaw(tok));
+ } else unreachable;
+ if (pp.top_expansion_buf.items.len != 0) {
+ pp.expansion_source_loc = pp.top_expansion_buf.items[0].loc;
+ try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, pp.top_expansion_buf.items.len, false, .expr);
+ }
+ for (pp.top_expansion_buf.items) |tok| {
+ if (tok.id == .macro_ws) continue;
+ if (!tok.id.validPreprocessorExprStart()) {
+ try pp.comp.diag.add(.{
+ .tag = .invalid_preproc_expr_start,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ return false;
+ }
+ break;
+ } else {
+ try pp.err(eof, .expected_value_in_expr);
+ return false;
+ }
+
+ // validate the tokens in the expression
+ try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
+ var i: usize = 0;
+ const items = pp.top_expansion_buf.items;
+ while (i < items.len) : (i += 1) {
+ var tok = items[i];
+ switch (tok.id) {
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ => {
+ try pp.comp.diag.add(.{
+ .tag = .string_literal_in_pp_expr,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ return false;
+ },
+ .plus_plus,
+ .minus_minus,
+ .plus_equal,
+ .minus_equal,
+ .asterisk_equal,
+ .slash_equal,
+ .percent_equal,
+ .angle_bracket_angle_bracket_left_equal,
+ .angle_bracket_angle_bracket_right_equal,
+ .ampersand_equal,
+ .caret_equal,
+ .pipe_equal,
+ .l_bracket,
+ .r_bracket,
+ .l_brace,
+ .r_brace,
+ .ellipsis,
+ .semicolon,
+ .hash,
+ .hash_hash,
+ .equal,
+ .arrow,
+ .period,
+ => {
+ try pp.comp.diag.add(.{
+ .tag = .invalid_preproc_operator,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ return false;
+ },
+ .macro_ws, .whitespace => continue,
+ .keyword_false => tok.id = .zero,
+ .keyword_true => tok.id = .one,
+ else => if (tok.id.isMacroIdentifier()) {
+ if (tok.id == .keyword_defined) {
+ const tokens_consumed = try pp.handleKeywordDefined(&tok, items[i + 1 ..], eof);
+ i += tokens_consumed;
+ } else {
+ try pp.comp.diag.add(.{
+ .tag = .undefined_macro,
+ .loc = tok.loc,
+ .extra = .{ .str = pp.expandedSlice(tok) },
+ }, tok.expansionSlice());
+
+ if (i + 1 < pp.top_expansion_buf.items.len and
+ pp.top_expansion_buf.items[i + 1].id == .l_paren)
+ {
+ try pp.comp.diag.add(.{
+ .tag = .fn_macro_undefined,
+ .loc = tok.loc,
+ .extra = .{ .str = pp.expandedSlice(tok) },
+ }, tok.expansionSlice());
+ return false;
+ }
+
+ tok.id = .zero; // undefined macro
+ }
+ },
+ }
+ pp.tokens.appendAssumeCapacity(tok);
+ }
+ try pp.tokens.append(pp.gpa, .{
+ .id = .eof,
+ .loc = tokFromRaw(eof).loc,
+ });
+
+ // Actually parse it.
+ var parser = Parser{
+ .pp = pp,
+ .comp = pp.comp,
+ .gpa = pp.gpa,
+ .tok_ids = pp.tokens.items(.id),
+ .tok_i = @intCast(start),
+ .arena = pp.arena.allocator(),
+ .in_macro = true,
+ .data = undefined,
+ .strings = undefined,
+ .retained_strings = undefined,
+ .value_map = undefined,
+ .labels = undefined,
+ .decl_buf = undefined,
+ .list_buf = undefined,
+ .param_buf = undefined,
+ .enum_buf = undefined,
+ .record_buf = undefined,
+ .attr_buf = undefined,
+ .field_attr_buf = undefined,
+ .string_ids = undefined,
+ };
+ return parser.macroExpr();
+}
+
+/// Turns macro_tok from .keyword_defined into .zero or .one depending on whether the argument is defined
+/// Returns the number of tokens consumed
+fn handleKeywordDefined(pp: *Preprocessor, macro_tok: *Token, tokens: []const Token, eof: RawToken) !usize {
+ std.debug.assert(macro_tok.id == .keyword_defined);
+ var it = TokenIterator.init(tokens);
+ const first = it.nextNoWS() orelse {
+ try pp.err(eof, .macro_name_missing);
+ return it.i;
+ };
+ switch (first.id) {
+ .l_paren => {},
+ else => {
+ if (!first.id.isMacroIdentifier()) {
+ try pp.comp.diag.add(.{
+ .tag = .macro_name_must_be_identifier,
+ .loc = first.loc,
+ .extra = .{ .str = pp.expandedSlice(first) },
+ }, first.expansionSlice());
+ }
+ macro_tok.id = if (pp.defines.contains(pp.expandedSlice(first))) .one else .zero;
+ return it.i;
+ },
+ }
+ const second = it.nextNoWS() orelse {
+ try pp.err(eof, .macro_name_missing);
+ return it.i;
+ };
+ if (!second.id.isMacroIdentifier()) {
+ try pp.comp.diag.add(.{
+ .tag = .macro_name_must_be_identifier,
+ .loc = second.loc,
+ }, second.expansionSlice());
+ return it.i;
+ }
+ macro_tok.id = if (pp.defines.contains(pp.expandedSlice(second))) .one else .zero;
+
+ const last = it.nextNoWS();
+ if (last == null or last.?.id != .r_paren) {
+ const tok = last orelse tokFromRaw(eof);
+ try pp.comp.diag.add(.{
+ .tag = .closing_paren,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ try pp.comp.diag.add(.{
+ .tag = .to_match_paren,
+ .loc = first.loc,
+ }, first.expansionSlice());
+ }
+
+ return it.i;
+}
+
+/// Skip until #else #elif #endif, return last directive token id.
+/// Also skips nested #if ... #endifs.
+fn skip(
+ pp: *Preprocessor,
+ tokenizer: *Tokenizer,
+ cont: enum { until_else, until_endif, until_endif_seen_else },
+) Error!void {
+ var ifs_seen: u32 = 0;
+ var line_start = true;
+ while (tokenizer.index < tokenizer.buf.len) {
+ if (line_start) {
+ const saved_tokenizer = tokenizer.*;
+ const hash = tokenizer.nextNoWS();
+ if (hash.id == .nl) continue;
+ line_start = false;
+ if (hash.id != .hash) continue;
+ const directive = tokenizer.nextNoWS();
+ switch (directive.id) {
+ .keyword_else => {
+ if (ifs_seen != 0) continue;
+ if (cont == .until_endif_seen_else) {
+ try pp.err(directive, .else_after_else);
+ continue;
+ }
+ tokenizer.* = saved_tokenizer;
+ return;
+ },
+ .keyword_elif => {
+ if (ifs_seen != 0 or cont == .until_endif) continue;
+ if (cont == .until_endif_seen_else) {
+ try pp.err(directive, .elif_after_else);
+ continue;
+ }
+ tokenizer.* = saved_tokenizer;
+ return;
+ },
+ .keyword_elifdef => {
+ if (ifs_seen != 0 or cont == .until_endif) continue;
+ if (cont == .until_endif_seen_else) {
+ try pp.err(directive, .elifdef_after_else);
+ continue;
+ }
+ tokenizer.* = saved_tokenizer;
+ return;
+ },
+ .keyword_elifndef => {
+ if (ifs_seen != 0 or cont == .until_endif) continue;
+ if (cont == .until_endif_seen_else) {
+ try pp.err(directive, .elifndef_after_else);
+ continue;
+ }
+ tokenizer.* = saved_tokenizer;
+ return;
+ },
+ .keyword_endif => {
+ if (ifs_seen == 0) {
+ tokenizer.* = saved_tokenizer;
+ return;
+ }
+ ifs_seen -= 1;
+ },
+ .keyword_if, .keyword_ifdef, .keyword_ifndef => ifs_seen += 1,
+ else => {},
+ }
+ } else if (tokenizer.buf[tokenizer.index] == '\n') {
+ line_start = true;
+ tokenizer.index += 1;
+ tokenizer.line += 1;
+ } else {
+ line_start = false;
+ tokenizer.index += 1;
+ }
+ } else {
+ const eof = tokenizer.next();
+ return pp.err(eof, .unterminated_conditional_directive);
+ }
+}
+
+// Skip until newline, ignore other tokens.
+fn skipToNl(tokenizer: *Tokenizer) void {
+ while (true) {
+ const tok = tokenizer.next();
+ if (tok.id == .nl or tok.id == .eof) return;
+ }
+}
+
+const ExpandBuf = std.ArrayList(Token);
+fn removePlacemarkers(buf: *ExpandBuf) void {
+ var i: usize = buf.items.len -% 1;
+ while (i < buf.items.len) : (i -%= 1) {
+ if (buf.items[i].id == .placemarker) {
+ const placemarker = buf.orderedRemove(i);
+ Token.free(placemarker.expansion_locs, buf.allocator);
+ }
+ }
+}
+
+const MacroArguments = std.ArrayList([]const Token);
+fn deinitMacroArguments(allocator: Allocator, args: *const MacroArguments) void {
+ for (args.items) |item| {
+ for (item) |tok| Token.free(tok.expansion_locs, allocator);
+ allocator.free(item);
+ }
+ args.deinit();
+}
+
+fn expandObjMacro(pp: *Preprocessor, simple_macro: *const Macro) Error!ExpandBuf {
+ var buf = ExpandBuf.init(pp.gpa);
+ errdefer buf.deinit();
+ try buf.ensureTotalCapacity(simple_macro.tokens.len);
+
+ // Add all of the simple_macros tokens to the new buffer handling any concats.
+ var i: usize = 0;
+ while (i < simple_macro.tokens.len) : (i += 1) {
+ const raw = simple_macro.tokens[i];
+ const tok = tokFromRaw(raw);
+ switch (raw.id) {
+ .hash_hash => {
+ var rhs = tokFromRaw(simple_macro.tokens[i + 1]);
+ i += 1;
+ while (rhs.id == .whitespace) {
+ rhs = tokFromRaw(simple_macro.tokens[i + 1]);
+ i += 1;
+ }
+ try pp.pasteTokens(&buf, &.{rhs});
+ },
+ .whitespace => if (pp.preserve_whitespace) buf.appendAssumeCapacity(tok),
+ .macro_file => {
+ const start = pp.comp.generated_buf.items.len;
+ const source = pp.comp.getSource(pp.expansion_source_loc.id);
+ try pp.comp.generated_buf.writer().print("\"{s}\"\n", .{source.path});
+
+ buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .string_literal, tok));
+ },
+ .macro_line => {
+ const start = pp.comp.generated_buf.items.len;
+ const source = pp.comp.getSource(pp.expansion_source_loc.id);
+ try pp.comp.generated_buf.writer().print("{d}\n", .{source.physicalLine(pp.expansion_source_loc)});
+
+ buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
+ },
+ .macro_counter => {
+ defer pp.counter += 1;
+ const start = pp.comp.generated_buf.items.len;
+ try pp.comp.generated_buf.writer().print("{d}\n", .{pp.counter});
+
+ buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
+ },
+ else => buf.appendAssumeCapacity(tok),
+ }
+ }
+
+ return buf;
+}
+
+/// Join a possibly-parenthesized series of string literal tokens into a single string without
+/// leading or trailing quotes. The returned slice is invalidated if pp.char_buf changes.
+/// Returns error.ExpectedStringLiteral if parentheses are not balanced, a non-string-literal
+/// is encountered, or if no string literals are encountered
+/// TODO: destringize (replace all '\\' with a single `\` and all '\"' with a '"')
+fn pasteStringsUnsafe(pp: *Preprocessor, toks: []const Token) ![]const u8 {
+ const char_top = pp.char_buf.items.len;
+ defer pp.char_buf.items.len = char_top;
+ var unwrapped = toks;
+ if (toks.len >= 2 and toks[0].id == .l_paren and toks[toks.len - 1].id == .r_paren) {
+ unwrapped = toks[1 .. toks.len - 1];
+ }
+ if (unwrapped.len == 0) return error.ExpectedStringLiteral;
+
+ for (unwrapped) |tok| {
+ if (tok.id == .macro_ws) continue;
+ if (tok.id != .string_literal) return error.ExpectedStringLiteral;
+ const str = pp.expandedSlice(tok);
+ try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
+ }
+ return pp.char_buf.items[char_top..];
+}
+
+/// Handle the _Pragma operator (implemented as a builtin macro)
+fn pragmaOperator(pp: *Preprocessor, arg_tok: Token, operator_loc: Source.Location) !void {
+ const arg_slice = pp.expandedSlice(arg_tok);
+ const content = arg_slice[1 .. arg_slice.len - 1];
+ const directive = "#pragma ";
+
+ pp.char_buf.clearRetainingCapacity();
+ const total_len = directive.len + content.len + 1; // destringify can never grow the string, + 1 for newline
+ try pp.char_buf.ensureUnusedCapacity(total_len);
+ pp.char_buf.appendSliceAssumeCapacity(directive);
+ pp.destringify(content);
+ pp.char_buf.appendAssumeCapacity('\n');
+
+ const start = pp.comp.generated_buf.items.len;
+ try pp.comp.generated_buf.appendSlice(pp.char_buf.items);
+ var tmp_tokenizer = Tokenizer{
+ .buf = pp.comp.generated_buf.items,
+ .comp = pp.comp,
+ .index = @intCast(start),
+ .source = .generated,
+ .line = pp.generated_line,
+ };
+ pp.generated_line += 1;
+ const hash_tok = tmp_tokenizer.next();
+ assert(hash_tok.id == .hash);
+ const pragma_tok = tmp_tokenizer.next();
+ assert(pragma_tok.id == .keyword_pragma);
+ try pp.pragma(&tmp_tokenizer, pragma_tok, operator_loc, arg_tok.expansionSlice());
+}
+
+/// Inverts the output of the preprocessor stringify (#) operation
+/// (except all whitespace is condensed to a single space)
+/// writes output to pp.char_buf; assumes capacity is sufficient
+/// backslash backslash -> backslash
+/// backslash doublequote -> doublequote
+/// All other characters remain the same
+fn destringify(pp: *Preprocessor, str: []const u8) void {
+ var state: enum { start, backslash_seen } = .start;
+ for (str) |c| {
+ switch (c) {
+ '\\' => {
+ if (state == .backslash_seen) pp.char_buf.appendAssumeCapacity(c);
+ state = if (state == .start) .backslash_seen else .start;
+ },
+ else => {
+ if (state == .backslash_seen and c != '"') pp.char_buf.appendAssumeCapacity('\\');
+ pp.char_buf.appendAssumeCapacity(c);
+ state = .start;
+ },
+ }
+ }
+}
+
+/// Stringify `tokens` into pp.char_buf.
+/// See https://gcc.gnu.org/onlinedocs/gcc-11.2.0/cpp/Stringizing.html#Stringizing
+fn stringify(pp: *Preprocessor, tokens: []const Token) !void {
+ try pp.char_buf.append('"');
+ var ws_state: enum { start, need, not_needed } = .start;
+ for (tokens) |tok| {
+ if (tok.id == .macro_ws) {
+ if (ws_state == .start) continue;
+ ws_state = .need;
+ continue;
+ }
+ if (ws_state == .need) try pp.char_buf.append(' ');
+ ws_state = .not_needed;
+
+ // backslashes not inside strings are not escaped
+ const is_str = switch (tok.id) {
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ .char_literal,
+ .char_literal_utf_16,
+ .char_literal_utf_32,
+ .char_literal_wide,
+ => true,
+ else => false,
+ };
+
+ for (pp.expandedSlice(tok)) |c| {
+ if (c == '"')
+ try pp.char_buf.appendSlice("\\\"")
+ else if (c == '\\' and is_str)
+ try pp.char_buf.appendSlice("\\\\")
+ else
+ try pp.char_buf.append(c);
+ }
+ }
+ if (pp.char_buf.items[pp.char_buf.items.len - 1] == '\\') {
+ const tok = tokens[tokens.len - 1];
+ try pp.comp.diag.add(.{
+ .tag = .invalid_pp_stringify_escape,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ pp.char_buf.items.len -= 1;
+ }
+ try pp.char_buf.appendSlice("\"\n");
+}
+
+fn reconstructIncludeString(pp: *Preprocessor, param_toks: []const Token) !?[]const u8 {
+ const char_top = pp.char_buf.items.len;
+ defer pp.char_buf.items.len = char_top;
+
+ // Trim leading/trailing whitespace
+ var begin: usize = 0;
+ var end: usize = param_toks.len;
+ while (begin < end and param_toks[begin].id == .macro_ws) : (begin += 1) {}
+ while (end > begin and param_toks[end - 1].id == .macro_ws) : (end -= 1) {}
+ const params = param_toks[begin..end];
+
+ if (params.len == 0) {
+ try pp.comp.diag.add(.{
+ .tag = .expected_filename,
+ .loc = param_toks[0].loc,
+ }, param_toks[0].expansionSlice());
+ return null;
+ }
+ // no string pasting
+ if (params[0].id == .string_literal and params.len > 1) {
+ try pp.comp.diag.add(.{
+ .tag = .closing_paren,
+ .loc = params[1].loc,
+ }, params[1].expansionSlice());
+ return null;
+ }
+
+ for (params) |tok| {
+ const str = pp.expandedSliceExtra(tok, .preserve_macro_ws);
+ try pp.char_buf.appendSlice(str);
+ }
+
+ const include_str = pp.char_buf.items[char_top..];
+ if (include_str.len < 3) {
+ try pp.comp.diag.add(.{
+ .tag = .empty_filename,
+ .loc = params[0].loc,
+ }, params[0].expansionSlice());
+ return null;
+ }
+
+ switch (include_str[0]) {
+ '<' => {
+ if (include_str[include_str.len - 1] != '>') {
+ // Ugly hack to find out where the '>' should go, since we don't have the closing ')' location
+ const start = params[0].loc;
+ try pp.comp.diag.add(.{
+ .tag = .header_str_closing,
+ .loc = .{ .id = start.id, .byte_offset = start.byte_offset + @as(u32, @intCast(include_str.len)) + 1, .line = start.line },
+ }, params[0].expansionSlice());
+ try pp.comp.diag.add(.{
+ .tag = .header_str_match,
+ .loc = params[0].loc,
+ }, params[0].expansionSlice());
+ return null;
+ }
+ return include_str;
+ },
+ '"' => return include_str,
+ else => {
+ try pp.comp.diag.add(.{
+ .tag = .expected_filename,
+ .loc = params[0].loc,
+ }, params[0].expansionSlice());
+ return null;
+ },
+ }
+}
+
+fn handleBuiltinMacro(pp: *Preprocessor, builtin: RawToken.Id, param_toks: []const Token, src_loc: Source.Location) Error!bool {
+ switch (builtin) {
+ .macro_param_has_attribute,
+ .macro_param_has_feature,
+ .macro_param_has_extension,
+ .macro_param_has_builtin,
+ => {
+ var invalid: ?Token = null;
+ var identifier: ?Token = null;
+ for (param_toks) |tok| {
+ if (tok.id == .macro_ws) continue;
+ if (!tok.id.isMacroIdentifier()) {
+ invalid = tok;
+ break;
+ }
+ if (identifier) |_| invalid = tok else identifier = tok;
+ }
+ if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
+ if (invalid) |some| {
+ try pp.comp.diag.add(
+ .{ .tag = .feature_check_requires_identifier, .loc = some.loc },
+ some.expansionSlice(),
+ );
+ return false;
+ }
+
+ const ident_str = pp.expandedSlice(identifier.?);
+ return switch (builtin) {
+ .macro_param_has_attribute => Attribute.fromString(.gnu, null, ident_str) != null,
+ .macro_param_has_feature => features.hasFeature(pp.comp, ident_str),
+ .macro_param_has_extension => features.hasExtension(pp.comp, ident_str),
+ .macro_param_has_builtin => pp.comp.hasBuiltin(ident_str),
+ else => unreachable,
+ };
+ },
+ .macro_param_has_warning => {
+ const actual_param = pp.pasteStringsUnsafe(param_toks) catch |er| switch (er) {
+ error.ExpectedStringLiteral => {
+ try pp.comp.diag.add(.{
+ .tag = .expected_str_literal_in,
+ .loc = param_toks[0].loc,
+ .extra = .{ .str = "__has_warning" },
+ }, param_toks[0].expansionSlice());
+ return false;
+ },
+ else => |e| return e,
+ };
+ if (!mem.startsWith(u8, actual_param, "-W")) {
+ try pp.comp.diag.add(.{
+ .tag = .malformed_warning_check,
+ .loc = param_toks[0].loc,
+ .extra = .{ .str = "__has_warning" },
+ }, param_toks[0].expansionSlice());
+ return false;
+ }
+ const warning_name = actual_param[2..];
+ return Diagnostics.warningExists(warning_name);
+ },
+ .macro_param_is_identifier => {
+ var invalid: ?Token = null;
+ var identifier: ?Token = null;
+ for (param_toks) |tok| switch (tok.id) {
+ .macro_ws => continue,
+ else => {
+ if (identifier) |_| invalid = tok else identifier = tok;
+ },
+ };
+ if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
+ if (invalid) |some| {
+ try pp.comp.diag.add(.{
+ .tag = .missing_tok_builtin,
+ .loc = some.loc,
+ .extra = .{ .tok_id_expected = .r_paren },
+ }, some.expansionSlice());
+ return false;
+ }
+
+ const id = identifier.?.id;
+ return id == .identifier or id == .extended_identifier;
+ },
+ .macro_param_has_include, .macro_param_has_include_next => {
+ const include_str = (try pp.reconstructIncludeString(param_toks)) orelse return false;
+ const include_type: Compilation.IncludeType = switch (include_str[0]) {
+ '"' => .quotes,
+ '<' => .angle_brackets,
+ else => unreachable,
+ };
+ const filename = include_str[1 .. include_str.len - 1];
+ if (builtin == .macro_param_has_include or pp.include_depth == 0) {
+ if (builtin == .macro_param_has_include_next) {
+ try pp.comp.diag.add(.{
+ .tag = .include_next_outside_header,
+ .loc = src_loc,
+ }, &.{});
+ }
+ return pp.comp.hasInclude(filename, src_loc.id, include_type, .first);
+ }
+ return pp.comp.hasInclude(filename, src_loc.id, include_type, .next);
+ },
+ else => unreachable,
+ }
+}
+
+fn expandFuncMacro(
+ pp: *Preprocessor,
+ loc: Source.Location,
+ func_macro: *const Macro,
+ args: *const MacroArguments,
+ expanded_args: *const MacroArguments,
+) MacroError!ExpandBuf {
+ var buf = ExpandBuf.init(pp.gpa);
+ try buf.ensureTotalCapacity(func_macro.tokens.len);
+ errdefer buf.deinit();
+
+ var expanded_variable_arguments = ExpandBuf.init(pp.gpa);
+ defer expanded_variable_arguments.deinit();
+ var variable_arguments = ExpandBuf.init(pp.gpa);
+ defer variable_arguments.deinit();
+
+ if (func_macro.var_args) {
+ var i: usize = func_macro.params.len;
+ while (i < expanded_args.items.len) : (i += 1) {
+ try variable_arguments.appendSlice(args.items[i]);
+ try expanded_variable_arguments.appendSlice(expanded_args.items[i]);
+ if (i != expanded_args.items.len - 1) {
+ const comma = Token{ .id = .comma, .loc = .{ .id = .generated } };
+ try variable_arguments.append(comma);
+ try expanded_variable_arguments.append(comma);
+ }
+ }
+ }
+
+ // token concatenation and expansion phase
+ var tok_i: usize = 0;
+ while (tok_i < func_macro.tokens.len) : (tok_i += 1) {
+ const raw = func_macro.tokens[tok_i];
+ switch (raw.id) {
+ .hash_hash => while (tok_i + 1 < func_macro.tokens.len) {
+ const raw_next = func_macro.tokens[tok_i + 1];
+ tok_i += 1;
+
+ const next = switch (raw_next.id) {
+ .macro_ws => continue,
+ .hash_hash => continue,
+ .macro_param, .macro_param_no_expand => if (args.items[raw_next.end].len > 0)
+ args.items[raw_next.end]
+ else
+ &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })},
+ .keyword_va_args => variable_arguments.items,
+ else => &[1]Token{tokFromRaw(raw_next)},
+ };
+
+ try pp.pasteTokens(&buf, next);
+ if (next.len != 0) break;
+ },
+ .macro_param_no_expand => {
+ const slice = if (args.items[raw.end].len > 0)
+ args.items[raw.end]
+ else
+ &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })};
+ const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
+ try bufCopyTokens(&buf, slice, &.{raw_loc});
+ },
+ .macro_param => {
+ const arg = expanded_args.items[raw.end];
+ const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
+ try bufCopyTokens(&buf, arg, &.{raw_loc});
+ },
+ .keyword_va_args => {
+ const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
+ try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
+ },
+ .stringify_param, .stringify_va_args => {
+ const arg = if (raw.id == .stringify_va_args)
+ variable_arguments.items
+ else
+ args.items[raw.end];
+
+ pp.char_buf.clearRetainingCapacity();
+ try pp.stringify(arg);
+
+ const start = pp.comp.generated_buf.items.len;
+ try pp.comp.generated_buf.appendSlice(pp.char_buf.items);
+
+ try buf.append(try pp.makeGeneratedToken(start, .string_literal, tokFromRaw(raw)));
+ },
+ .macro_param_has_attribute,
+ .macro_param_has_warning,
+ .macro_param_has_feature,
+ .macro_param_has_extension,
+ .macro_param_has_builtin,
+ .macro_param_has_include,
+ .macro_param_has_include_next,
+ .macro_param_is_identifier,
+ => {
+ const arg = expanded_args.items[0];
+ const result = if (arg.len == 0) blk: {
+ const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
+ try pp.comp.diag.add(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
+ break :blk false;
+ } else try pp.handleBuiltinMacro(raw.id, arg, loc);
+ const start = pp.comp.generated_buf.items.len;
+ try pp.comp.generated_buf.writer().print("{}\n", .{@intFromBool(result)});
+ try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
+ },
+ .macro_param_pragma_operator => {
+ const param_toks = expanded_args.items[0];
+ // Clang and GCC require exactly one token (so, no parentheses or string pasting)
+ // even though their error messages indicate otherwise. Ours is slightly more
+ // descriptive.
+ var invalid: ?Token = null;
+ var string: ?Token = null;
+ for (param_toks) |tok| switch (tok.id) {
+ .string_literal => {
+ if (string) |_| invalid = tok else string = tok;
+ },
+ .macro_ws => continue,
+ else => {
+ invalid = tok;
+ break;
+ },
+ };
+ if (string == null and invalid == null) invalid = .{ .loc = loc, .id = .eof };
+ if (invalid) |some| try pp.comp.diag.add(
+ .{ .tag = .pragma_operator_string_literal, .loc = some.loc },
+ some.expansionSlice(),
+ ) else try pp.pragmaOperator(string.?, loc);
+ },
+ .comma => {
+ if (tok_i + 2 < func_macro.tokens.len and func_macro.tokens[tok_i + 1].id == .hash_hash) {
+ const hash_hash = func_macro.tokens[tok_i + 1];
+ var maybe_va_args = func_macro.tokens[tok_i + 2];
+ var consumed: usize = 2;
+ if (maybe_va_args.id == .macro_ws and tok_i + 3 < func_macro.tokens.len) {
+ consumed = 3;
+ maybe_va_args = func_macro.tokens[tok_i + 3];
+ }
+ if (maybe_va_args.id == .keyword_va_args) {
+ // GNU extension: `, ##__VA_ARGS__` deletes the comma if __VA_ARGS__ is empty
+ tok_i += consumed;
+ if (func_macro.params.len == expanded_args.items.len) {
+ // Empty __VA_ARGS__, drop the comma
+ try pp.err(hash_hash, .comma_deletion_va_args);
+ } else if (func_macro.params.len == 0 and expanded_args.items.len == 1 and expanded_args.items[0].len == 0) {
+ // Ambiguous whether this is "empty __VA_ARGS__" or "__VA_ARGS__ omitted"
+ if (pp.comp.langopts.standard.isGNU()) {
+ // GNU standard, drop the comma
+ try pp.err(hash_hash, .comma_deletion_va_args);
+ } else {
+ // C standard, retain the comma
+ try buf.append(tokFromRaw(raw));
+ }
+ } else {
+ try buf.append(tokFromRaw(raw));
+ if (expanded_variable_arguments.items.len > 0 or variable_arguments.items.len == func_macro.params.len) {
+ try pp.err(hash_hash, .comma_deletion_va_args);
+ }
+ const raw_loc = Source.Location{
+ .id = maybe_va_args.source,
+ .byte_offset = maybe_va_args.start,
+ .line = maybe_va_args.line,
+ };
+ try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
+ }
+ continue;
+ }
+ }
+ // Regular comma, no token pasting with __VA_ARGS__
+ try buf.append(tokFromRaw(raw));
+ },
+ else => try buf.append(tokFromRaw(raw)),
+ }
+ }
+ removePlacemarkers(&buf);
+
+ return buf;
+}
+
+fn shouldExpand(tok: Token, macro: *Macro) bool {
+ // macro.loc.line contains the macros end index
+ if (tok.loc.id == macro.loc.id and
+ tok.loc.byte_offset >= macro.loc.byte_offset and
+ tok.loc.byte_offset <= macro.loc.line)
+ return false;
+ for (tok.expansionSlice()) |loc| {
+ if (loc.id == macro.loc.id and
+ loc.byte_offset >= macro.loc.byte_offset and
+ loc.byte_offset <= macro.loc.line)
+ return false;
+ }
+ if (tok.flags.expansion_disabled) return false;
+
+ return true;
+}
+
+fn bufCopyTokens(buf: *ExpandBuf, tokens: []const Token, src: []const Source.Location) !void {
+ try buf.ensureUnusedCapacity(tokens.len);
+ for (tokens) |tok| {
+ var copy = try tok.dupe(buf.allocator);
+ errdefer Token.free(copy.expansion_locs, buf.allocator);
+ try copy.addExpansionLocation(buf.allocator, src);
+ buf.appendAssumeCapacity(copy);
+ }
+}
+
+fn nextBufToken(
+ pp: *Preprocessor,
+ tokenizer: *Tokenizer,
+ buf: *ExpandBuf,
+ start_idx: *usize,
+ end_idx: *usize,
+ extend_buf: bool,
+) Error!Token {
+ start_idx.* += 1;
+ if (start_idx.* == buf.items.len and start_idx.* >= end_idx.*) {
+ if (extend_buf) {
+ const raw_tok = tokenizer.next();
+ if (raw_tok.id.isMacroIdentifier() and
+ pp.poisoned_identifiers.get(pp.tokSlice(raw_tok)) != null)
+ try pp.err(raw_tok, .poisoned_identifier);
+
+ if (raw_tok.id == .nl) pp.add_expansion_nl += 1;
+
+ const new_tok = tokFromRaw(raw_tok);
+ end_idx.* += 1;
+ try buf.append(new_tok);
+ return new_tok;
+ } else {
+ return Token{ .id = .eof, .loc = .{ .id = .generated } };
+ }
+ } else {
+ return buf.items[start_idx.*];
+ }
+}
+
+fn collectMacroFuncArguments(
+ pp: *Preprocessor,
+ tokenizer: *Tokenizer,
+ buf: *ExpandBuf,
+ start_idx: *usize,
+ end_idx: *usize,
+ extend_buf: bool,
+ is_builtin: bool,
+) !MacroArguments {
+ const name_tok = buf.items[start_idx.*];
+ const saved_tokenizer = tokenizer.*;
+ const old_end = end_idx.*;
+
+ while (true) {
+ const tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
+ switch (tok.id) {
+ .nl, .whitespace, .macro_ws => {},
+ .l_paren => break,
+ else => {
+ if (is_builtin) {
+ try pp.comp.diag.add(.{
+ .tag = .missing_lparen_after_builtin,
+ .loc = name_tok.loc,
+ .extra = .{ .str = pp.expandedSlice(name_tok) },
+ }, tok.expansionSlice());
+ }
+ // Not a macro function call, go over normal identifier, rewind
+ tokenizer.* = saved_tokenizer;
+ end_idx.* = old_end;
+ return error.MissingLParen;
+ },
+ }
+ }
+
+ // collect the arguments.
+ var parens: u32 = 0;
+ var args = MacroArguments.init(pp.gpa);
+ errdefer deinitMacroArguments(pp.gpa, &args);
+ var curArgument = std.ArrayList(Token).init(pp.gpa);
+ defer curArgument.deinit();
+ while (true) {
+ var tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
+ tok.flags.is_macro_arg = true;
+ switch (tok.id) {
+ .comma => {
+ if (parens == 0) {
+ const owned = try curArgument.toOwnedSlice();
+ errdefer pp.gpa.free(owned);
+ try args.append(owned);
+ } else {
+ const duped = try tok.dupe(pp.gpa);
+ errdefer Token.free(duped.expansion_locs, pp.gpa);
+ try curArgument.append(duped);
+ }
+ },
+ .l_paren => {
+ const duped = try tok.dupe(pp.gpa);
+ errdefer Token.free(duped.expansion_locs, pp.gpa);
+ try curArgument.append(duped);
+ parens += 1;
+ },
+ .r_paren => {
+ if (parens == 0) {
+ const owned = try curArgument.toOwnedSlice();
+ errdefer pp.gpa.free(owned);
+ try args.append(owned);
+ break;
+ } else {
+ const duped = try tok.dupe(pp.gpa);
+ errdefer Token.free(duped.expansion_locs, pp.gpa);
+ try curArgument.append(duped);
+ parens -= 1;
+ }
+ },
+ .eof => {
+ {
+ const owned = try curArgument.toOwnedSlice();
+ errdefer pp.gpa.free(owned);
+ try args.append(owned);
+ }
+ tokenizer.* = saved_tokenizer;
+ try pp.comp.diag.add(
+ .{ .tag = .unterminated_macro_arg_list, .loc = name_tok.loc },
+ name_tok.expansionSlice(),
+ );
+ return error.Unterminated;
+ },
+ .nl, .whitespace => {
+ try curArgument.append(.{ .id = .macro_ws, .loc = tok.loc });
+ },
+ else => {
+ const duped = try tok.dupe(pp.gpa);
+ errdefer Token.free(duped.expansion_locs, pp.gpa);
+ try curArgument.append(duped);
+ },
+ }
+ }
+
+ return args;
+}
+
+fn removeExpandedTokens(pp: *Preprocessor, buf: *ExpandBuf, start: usize, len: usize, moving_end_idx: *usize) !void {
+ for (buf.items[start .. start + len]) |tok| Token.free(tok.expansion_locs, pp.gpa);
+ try buf.replaceRange(start, len, &.{});
+ moving_end_idx.* -|= len;
+}
+
+/// The behavior of `defined` depends on whether we are in a preprocessor
+/// expression context (#if or #elif) or not.
+/// In a non-expression context it's just an identifier. Within a preprocessor
+/// expression it is a unary operator or one-argument function.
+const EvalContext = enum {
+ expr,
+ non_expr,
+};
+
+/// Helper for safely iterating over a slice of tokens while skipping whitespace
+const TokenIterator = struct {
+ toks: []const Token,
+ i: usize,
+
+ fn init(toks: []const Token) TokenIterator {
+ return .{ .toks = toks, .i = 0 };
+ }
+
+ fn nextNoWS(self: *TokenIterator) ?Token {
+ while (self.i < self.toks.len) : (self.i += 1) {
+ const tok = self.toks[self.i];
+ if (tok.id == .whitespace or tok.id == .macro_ws) continue;
+
+ self.i += 1;
+ return tok;
+ }
+ return null;
+ }
+};
+
+fn expandMacroExhaustive(
+ pp: *Preprocessor,
+ tokenizer: *Tokenizer,
+ buf: *ExpandBuf,
+ start_idx: usize,
+ end_idx: usize,
+ extend_buf: bool,
+ eval_ctx: EvalContext,
+) MacroError!void {
+ var moving_end_idx = end_idx;
+ var advance_index: usize = 0;
+ // rescan loop
+ var do_rescan = true;
+ while (do_rescan) {
+ do_rescan = false;
+ // expansion loop
+ var idx: usize = start_idx + advance_index;
+ while (idx < moving_end_idx) {
+ const macro_tok = buf.items[idx];
+ if (macro_tok.id == .keyword_defined and eval_ctx == .expr) {
+ idx += 1;
+ var it = TokenIterator.init(buf.items[idx..moving_end_idx]);
+ if (it.nextNoWS()) |tok| {
+ switch (tok.id) {
+ .l_paren => {
+ _ = it.nextNoWS(); // eat (what should be) identifier
+ _ = it.nextNoWS(); // eat (what should be) r paren
+ },
+ .identifier, .extended_identifier => {},
+ else => {},
+ }
+ }
+ idx += it.i;
+ continue;
+ }
+ const macro_entry = pp.defines.getPtr(pp.expandedSlice(macro_tok));
+ if (macro_entry == null or !shouldExpand(buf.items[idx], macro_entry.?)) {
+ idx += 1;
+ continue;
+ }
+ if (macro_entry) |macro| macro_handler: {
+ if (macro.is_func) {
+ var macro_scan_idx = idx;
+ // to be saved in case this doesn't turn out to be a call
+ const args = pp.collectMacroFuncArguments(
+ tokenizer,
+ buf,
+ ¯o_scan_idx,
+ &moving_end_idx,
+ extend_buf,
+ macro.is_builtin,
+ ) catch |er| switch (er) {
+ error.MissingLParen => {
+ if (!buf.items[idx].flags.is_macro_arg) buf.items[idx].flags.expansion_disabled = true;
+ idx += 1;
+ break :macro_handler;
+ },
+ error.Unterminated => {
+ if (pp.comp.langopts.emulate == .gcc) idx += 1;
+ try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx, &moving_end_idx);
+ break :macro_handler;
+ },
+ else => |e| return e,
+ };
+ defer {
+ for (args.items) |item| {
+ pp.gpa.free(item);
+ }
+ args.deinit();
+ }
+
+ var args_count: u32 = @intCast(args.items.len);
+ // if the macro has zero arguments g() args_count is still 1
+ // an empty token list g() and a whitespace-only token list g( )
+ // counts as zero arguments for the purposes of argument-count validation
+ if (args_count == 1 and macro.params.len == 0) {
+ for (args.items[0]) |tok| {
+ if (tok.id != .macro_ws) break;
+ } else {
+ args_count = 0;
+ }
+ }
+
+ // Validate argument count.
+ const extra = Diagnostics.Message.Extra{
+ .arguments = .{ .expected = @intCast(macro.params.len), .actual = args_count },
+ };
+ if (macro.var_args and args_count < macro.params.len) {
+ try pp.comp.diag.add(
+ .{ .tag = .expected_at_least_arguments, .loc = buf.items[idx].loc, .extra = extra },
+ buf.items[idx].expansionSlice(),
+ );
+ idx += 1;
+ try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
+ continue;
+ }
+ if (!macro.var_args and args_count != macro.params.len) {
+ try pp.comp.diag.add(
+ .{ .tag = .expected_arguments, .loc = buf.items[idx].loc, .extra = extra },
+ buf.items[idx].expansionSlice(),
+ );
+ idx += 1;
+ try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
+ continue;
+ }
+ var expanded_args = MacroArguments.init(pp.gpa);
+ defer deinitMacroArguments(pp.gpa, &expanded_args);
+ try expanded_args.ensureTotalCapacity(args.items.len);
+ for (args.items) |arg| {
+ var expand_buf = ExpandBuf.init(pp.gpa);
+ errdefer expand_buf.deinit();
+ try expand_buf.appendSlice(arg);
+
+ try pp.expandMacroExhaustive(tokenizer, &expand_buf, 0, expand_buf.items.len, false, eval_ctx);
+
+ expanded_args.appendAssumeCapacity(try expand_buf.toOwnedSlice());
+ }
+
+ var res = try pp.expandFuncMacro(macro_tok.loc, macro, &args, &expanded_args);
+ defer res.deinit();
+ const tokens_added = res.items.len;
+
+ const macro_expansion_locs = macro_tok.expansionSlice();
+ for (res.items) |*tok| {
+ try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
+ try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
+ }
+
+ const tokens_removed = macro_scan_idx - idx + 1;
+ for (buf.items[idx .. idx + tokens_removed]) |tok| Token.free(tok.expansion_locs, pp.gpa);
+ try buf.replaceRange(idx, tokens_removed, res.items);
+
+ moving_end_idx += tokens_added;
+ // Overflow here means that we encountered an unterminated argument list
+ // while expanding the body of this macro.
+ moving_end_idx -|= tokens_removed;
+ idx += tokens_added;
+ do_rescan = true;
+ } else {
+ const res = try pp.expandObjMacro(macro);
+ defer res.deinit();
+
+ const macro_expansion_locs = macro_tok.expansionSlice();
+ var increment_idx_by = res.items.len;
+ for (res.items, 0..) |*tok, i| {
+ tok.flags.is_macro_arg = macro_tok.flags.is_macro_arg;
+ try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
+ try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
+ if (tok.id == .keyword_defined and eval_ctx == .expr) {
+ try pp.comp.diag.add(.{
+ .tag = .expansion_to_defined,
+ .loc = tok.loc,
+ }, tok.expansionSlice());
+ }
+
+ if (i < increment_idx_by and (tok.id == .keyword_defined or pp.defines.contains(pp.expandedSlice(tok.*)))) {
+ increment_idx_by = i;
+ }
+ }
+
+ Token.free(buf.items[idx].expansion_locs, pp.gpa);
+ try buf.replaceRange(idx, 1, res.items);
+ idx += increment_idx_by;
+ moving_end_idx = moving_end_idx + res.items.len - 1;
+ do_rescan = true;
+ }
+ }
+ if (idx - start_idx == advance_index + 1 and !do_rescan) {
+ advance_index += 1;
+ }
+ } // end of replacement phase
+ }
+ // end of scanning phase
+
+ // trim excess buffer
+ for (buf.items[moving_end_idx..]) |item| {
+ Token.free(item.expansion_locs, pp.gpa);
+ }
+ buf.items.len = moving_end_idx;
+}
+
+/// Try to expand a macro after a possible candidate has been read from the `tokenizer`
+/// into the `raw` token passed as argument
+fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroError!void {
+ var source_tok = tokFromRaw(raw);
+ if (!raw.id.isMacroIdentifier()) {
+ source_tok.id.simplifyMacroKeyword();
+ return pp.tokens.append(pp.gpa, source_tok);
+ }
+ pp.top_expansion_buf.items.len = 0;
+ try pp.top_expansion_buf.append(source_tok);
+ pp.expansion_source_loc = source_tok.loc;
+
+ try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr);
+ try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
+ for (pp.top_expansion_buf.items) |*tok| {
+ if (tok.id == .macro_ws and !pp.preserve_whitespace) {
+ Token.free(tok.expansion_locs, pp.gpa);
+ continue;
+ }
+ tok.id.simplifyMacroKeywordExtra(true);
+ pp.tokens.appendAssumeCapacity(tok.*);
+ }
+ if (pp.preserve_whitespace) {
+ try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.add_expansion_nl);
+ while (pp.add_expansion_nl > 0) : (pp.add_expansion_nl -= 1) {
+ pp.tokens.appendAssumeCapacity(.{ .id = .nl, .loc = .{ .id = .generated } });
+ }
+ }
+}
+
+fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 {
+ if (tok.id.lexeme()) |some| {
+ if (!tok.id.allowsDigraphs(pp.comp) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some;
+ }
+ var tmp_tokenizer = Tokenizer{
+ .buf = pp.comp.getSource(tok.loc.id).buf,
+ .comp = pp.comp,
+ .index = tok.loc.byte_offset,
+ .source = .generated,
+ };
+ if (tok.id == .macro_string) {
+ while (true) : (tmp_tokenizer.index += 1) {
+ if (tmp_tokenizer.buf[tmp_tokenizer.index] == '>') break;
+ }
+ return tmp_tokenizer.buf[tok.loc.byte_offset .. tmp_tokenizer.index + 1];
+ }
+ const res = tmp_tokenizer.next();
+ return tmp_tokenizer.buf[res.start..res.end];
+}
+
+/// Get expanded token source string.
+pub fn expandedSlice(pp: *Preprocessor, tok: Token) []const u8 {
+ return pp.expandedSliceExtra(tok, .single_macro_ws);
+}
+
+/// Concat two tokens and add the result to pp.generated
+fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token) Error!void {
+ const lhs = while (lhs_toks.popOrNull()) |lhs| {
+ if (lhs.id == .macro_ws)
+ Token.free(lhs.expansion_locs, pp.gpa)
+ else
+ break lhs;
+ } else {
+ return bufCopyTokens(lhs_toks, rhs_toks, &.{});
+ };
+
+ var rhs_rest: u32 = 1;
+ const rhs = for (rhs_toks) |rhs| {
+ if (rhs.id != .macro_ws) break rhs;
+ rhs_rest += 1;
+ } else {
+ return lhs_toks.appendAssumeCapacity(lhs);
+ };
+ defer Token.free(lhs.expansion_locs, pp.gpa);
+
+ const start = pp.comp.generated_buf.items.len;
+ const end = start + pp.expandedSlice(lhs).len + pp.expandedSlice(rhs).len;
+ try pp.comp.generated_buf.ensureTotalCapacity(end + 1); // +1 for a newline
+ // We cannot use the same slices here since they might be invalidated by `ensureCapacity`
+ pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(lhs));
+ pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(rhs));
+ pp.comp.generated_buf.appendAssumeCapacity('\n');
+
+ // Try to tokenize the result.
+ var tmp_tokenizer = Tokenizer{
+ .buf = pp.comp.generated_buf.items,
+ .comp = pp.comp,
+ .index = @intCast(start),
+ .source = .generated,
+ };
+ const pasted_token = tmp_tokenizer.nextNoWS();
+ const next = tmp_tokenizer.nextNoWS().id;
+ if (next != .nl and next != .eof) {
+ try pp.comp.diag.add(.{
+ .tag = .pasting_formed_invalid,
+ .loc = lhs.loc,
+ .extra = .{ .str = try pp.comp.diag.arena.allocator().dupe(
+ u8,
+ pp.comp.generated_buf.items[start..end],
+ ) },
+ }, lhs.expansionSlice());
+ }
+
+ const pasted_id = if (lhs.id == .placemarker and rhs.id == .placemarker)
+ .placemarker
+ else
+ pasted_token.id;
+ try lhs_toks.append(try pp.makeGeneratedToken(start, pasted_id, lhs));
+ try bufCopyTokens(lhs_toks, rhs_toks[rhs_rest..], &.{});
+}
+
+fn makeGeneratedToken(pp: *Preprocessor, start: usize, id: Token.Id, source: Token) !Token {
+ var pasted_token = Token{ .id = id, .loc = .{
+ .id = .generated,
+ .byte_offset = @intCast(start),
+ .line = pp.generated_line,
+ } };
+ pp.generated_line += 1;
+ try pasted_token.addExpansionLocation(pp.gpa, &.{source.loc});
+ try pasted_token.addExpansionLocation(pp.gpa, source.expansionSlice());
+ return pasted_token;
+}
+
+/// Defines a new macro and warns if it is a duplicate
+fn defineMacro(pp: *Preprocessor, name_tok: RawToken, macro: Macro) Error!void {
+ const name_str = pp.tokSlice(name_tok);
+ const gop = try pp.defines.getOrPut(name_str);
+ if (gop.found_existing and !gop.value_ptr.eql(macro, pp)) {
+ try pp.comp.diag.add(.{
+ .tag = if (gop.value_ptr.is_builtin) .builtin_macro_redefined else .macro_redefined,
+ .loc = .{ .id = name_tok.source, .byte_offset = name_tok.start, .line = name_tok.line },
+ .extra = .{ .str = name_str },
+ }, &.{});
+ // TODO add a previous definition note
+ }
+ if (pp.verbose) {
+ pp.verboseLog(name_tok, "macro {s} defined", .{name_str});
+ }
+ gop.value_ptr.* = macro;
+}
+
+/// Handle a #define directive.
+fn define(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
+ // Get macro name and validate it.
+ const macro_name = tokenizer.nextNoWS();
+ if (macro_name.id == .keyword_defined) {
+ try pp.err(macro_name, .defined_as_macro_name);
+ return skipToNl(tokenizer);
+ }
+ if (!macro_name.id.isMacroIdentifier()) {
+ try pp.err(macro_name, .macro_name_must_be_identifier);
+ return skipToNl(tokenizer);
+ }
+ var macro_name_token_id = macro_name.id;
+ macro_name_token_id.simplifyMacroKeyword();
+ switch (macro_name_token_id) {
+ .identifier, .extended_identifier => {},
+ else => if (macro_name_token_id.isMacroIdentifier()) {
+ try pp.err(macro_name, .keyword_macro);
+ },
+ }
+
+ // Check for function macros and empty defines.
+ var first = tokenizer.next();
+ switch (first.id) {
+ .nl, .eof => return pp.defineMacro(macro_name, .{
+ .params = undefined,
+ .tokens = undefined,
+ .var_args = false,
+ .loc = undefined,
+ .is_func = false,
+ }),
+ .whitespace => first = tokenizer.next(),
+ .l_paren => return pp.defineFn(tokenizer, macro_name, first),
+ else => try pp.err(first, .whitespace_after_macro_name),
+ }
+ if (first.id == .hash_hash) {
+ try pp.err(first, .hash_hash_at_start);
+ return skipToNl(tokenizer);
+ }
+ first.id.simplifyMacroKeyword();
+
+ pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
+
+ var need_ws = false;
+ // Collect the token body and validate any ## found.
+ var tok = first;
+ const end_index = while (true) {
+ tok.id.simplifyMacroKeyword();
+ switch (tok.id) {
+ .hash_hash => {
+ const next = tokenizer.nextNoWS();
+ switch (next.id) {
+ .nl, .eof => {
+ try pp.err(tok, .hash_hash_at_end);
+ return;
+ },
+ .hash_hash => {
+ try pp.err(next, .hash_hash_at_end);
+ return;
+ },
+ else => {},
+ }
+ try pp.token_buf.append(tok);
+ try pp.token_buf.append(next);
+ },
+ .nl, .eof => break tok.start,
+ .whitespace => need_ws = true,
+ else => {
+ if (tok.id != .whitespace and need_ws) {
+ need_ws = false;
+ try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
+ }
+ try pp.token_buf.append(tok);
+ },
+ }
+ tok = tokenizer.next();
+ } else unreachable;
+
+ const list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
+ try pp.defineMacro(macro_name, .{
+ .loc = .{
+ .id = macro_name.source,
+ .byte_offset = first.start,
+ .line = end_index,
+ },
+ .tokens = list,
+ .params = undefined,
+ .is_func = false,
+ .var_args = false,
+ });
+}
+
+/// Handle a function like #define directive.
+fn defineFn(pp: *Preprocessor, tokenizer: *Tokenizer, macro_name: RawToken, l_paren: RawToken) Error!void {
+ assert(macro_name.id.isMacroIdentifier());
+ var params = std.ArrayList([]const u8).init(pp.gpa);
+ defer params.deinit();
+
+ // Parse the parameter list.
+ var gnu_var_args: []const u8 = "";
+ var var_args = false;
+ const start_index = while (true) {
+ var tok = tokenizer.nextNoWS();
+ if (tok.id == .r_paren) break tok.end;
+ if (tok.id == .eof) return pp.err(tok, .unterminated_macro_param_list);
+ if (tok.id == .ellipsis) {
+ var_args = true;
+ const r_paren = tokenizer.nextNoWS();
+ if (r_paren.id != .r_paren) {
+ try pp.err(r_paren, .missing_paren_param_list);
+ try pp.err(l_paren, .to_match_paren);
+ return skipToNl(tokenizer);
+ }
+ break r_paren.end;
+ }
+ if (!tok.id.isMacroIdentifier()) {
+ try pp.err(tok, .invalid_token_param_list);
+ return skipToNl(tokenizer);
+ }
+
+ try params.append(pp.tokSlice(tok));
+
+ tok = tokenizer.nextNoWS();
+ if (tok.id == .ellipsis) {
+ try pp.err(tok, .gnu_va_macro);
+ gnu_var_args = params.pop();
+ const r_paren = tokenizer.nextNoWS();
+ if (r_paren.id != .r_paren) {
+ try pp.err(r_paren, .missing_paren_param_list);
+ try pp.err(l_paren, .to_match_paren);
+ return skipToNl(tokenizer);
+ }
+ break r_paren.end;
+ } else if (tok.id == .r_paren) {
+ break tok.end;
+ } else if (tok.id != .comma) {
+ try pp.err(tok, .expected_comma_param_list);
+ return skipToNl(tokenizer);
+ }
+ } else unreachable;
+
+ var need_ws = false;
+ // Collect the body tokens and validate # and ##'s found.
+ pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
+ const end_index = tok_loop: while (true) {
+ var tok = tokenizer.next();
+ switch (tok.id) {
+ .nl, .eof => break tok.start,
+ .whitespace => need_ws = pp.token_buf.items.len != 0,
+ .hash => {
+ if (tok.id != .whitespace and need_ws) {
+ need_ws = false;
+ try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
+ }
+ const param = tokenizer.nextNoWS();
+ blk: {
+ if (var_args and param.id == .keyword_va_args) {
+ tok.id = .stringify_va_args;
+ try pp.token_buf.append(tok);
+ continue :tok_loop;
+ }
+ if (!param.id.isMacroIdentifier()) break :blk;
+ const s = pp.tokSlice(param);
+ if (mem.eql(u8, s, gnu_var_args)) {
+ tok.id = .stringify_va_args;
+ try pp.token_buf.append(tok);
+ continue :tok_loop;
+ }
+ for (params.items, 0..) |p, i| {
+ if (mem.eql(u8, p, s)) {
+ tok.id = .stringify_param;
+ tok.end = @intCast(i);
+ try pp.token_buf.append(tok);
+ continue :tok_loop;
+ }
+ }
+ }
+ try pp.err(param, .hash_not_followed_param);
+ return skipToNl(tokenizer);
+ },
+ .hash_hash => {
+ need_ws = false;
+ // if ## appears at the beginning, the token buf is still empty
+ // in this case, error out
+ if (pp.token_buf.items.len == 0) {
+ try pp.err(tok, .hash_hash_at_start);
+ return skipToNl(tokenizer);
+ }
+ const saved_tokenizer = tokenizer.*;
+ const next = tokenizer.nextNoWS();
+ if (next.id == .nl or next.id == .eof) {
+ try pp.err(tok, .hash_hash_at_end);
+ return;
+ }
+ tokenizer.* = saved_tokenizer;
+ // convert the previous token to .macro_param_no_expand if it was .macro_param
+ if (pp.token_buf.items[pp.token_buf.items.len - 1].id == .macro_param) {
+ pp.token_buf.items[pp.token_buf.items.len - 1].id = .macro_param_no_expand;
+ }
+ try pp.token_buf.append(tok);
+ },
+ else => {
+ if (tok.id != .whitespace and need_ws) {
+ need_ws = false;
+ try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
+ }
+ if (var_args and tok.id == .keyword_va_args) {
+ // do nothing
+ } else if (tok.id.isMacroIdentifier()) {
+ tok.id.simplifyMacroKeyword();
+ const s = pp.tokSlice(tok);
+ if (mem.eql(u8, gnu_var_args, s)) {
+ tok.id = .keyword_va_args;
+ } else for (params.items, 0..) |param, i| {
+ if (mem.eql(u8, param, s)) {
+ // NOTE: it doesn't matter to assign .macro_param_no_expand
+ // here in case a ## was the previous token, because
+ // ## processing will eat this token with the same semantics
+ tok.id = .macro_param;
+ tok.end = @intCast(i);
+ break;
+ }
+ }
+ }
+ try pp.token_buf.append(tok);
+ },
+ }
+ } else unreachable;
+
+ const param_list = try pp.arena.allocator().dupe([]const u8, params.items);
+ const token_list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
+ try pp.defineMacro(macro_name, .{
+ .is_func = true,
+ .params = param_list,
+ .var_args = var_args or gnu_var_args.len != 0,
+ .tokens = token_list,
+ .loc = .{
+ .id = macro_name.source,
+ .byte_offset = start_index,
+ .line = end_index,
+ },
+ });
+}
+
+/// Handle an #embed directive
+fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
+ const first = tokenizer.nextNoWS();
+ const filename_tok = pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof) catch |er| switch (er) {
+ error.InvalidInclude => return,
+ else => |e| return e,
+ };
+
+ // Check for empty filename.
+ const tok_slice = pp.expandedSlice(filename_tok);
+ if (tok_slice.len < 3) {
+ try pp.err(first, .empty_filename);
+ return;
+ }
+ const filename = tok_slice[1 .. tok_slice.len - 1];
+ const include_type: Compilation.IncludeType = switch (filename_tok.id) {
+ .string_literal => .quotes,
+ .macro_string => .angle_brackets,
+ else => unreachable,
+ };
+
+ const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type)) orelse return pp.fatal(first, "'{s}' not found", .{filename});
+ defer pp.comp.gpa.free(embed_bytes);
+
+ if (embed_bytes.len == 0) return;
+
+ try pp.tokens.ensureUnusedCapacity(pp.comp.gpa, 2 * embed_bytes.len - 1); // N bytes and N-1 commas
+
+ // TODO: We currently only support systems with CHAR_BIT == 8
+ // If the target's CHAR_BIT is not 8, we need to write out correctly-sized embed_bytes
+ // and correctly account for the target's endianness
+ const writer = pp.comp.generated_buf.writer();
+
+ {
+ const byte = embed_bytes[0];
+ const start = pp.comp.generated_buf.items.len;
+ try writer.print("{d}", .{byte});
+ pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start, .embed_byte, filename_tok));
+ }
+
+ for (embed_bytes[1..]) |byte| {
+ const start = pp.comp.generated_buf.items.len;
+ try writer.print(",{d}", .{byte});
+ pp.tokens.appendAssumeCapacity(.{ .id = .comma, .loc = .{ .id = .generated, .byte_offset = @intCast(start) } });
+ pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start + 1, .embed_byte, filename_tok));
+ }
+ try pp.comp.generated_buf.append('\n');
+}
+
+// Handle a #include directive.
+fn include(pp: *Preprocessor, tokenizer: *Tokenizer, which: Compilation.WhichInclude) MacroError!void {
+ const first = tokenizer.nextNoWS();
+ const new_source = findIncludeSource(pp, tokenizer, first, which) catch |er| switch (er) {
+ error.InvalidInclude => return,
+ else => |e| return e,
+ };
+
+ // Prevent stack overflow
+ pp.include_depth += 1;
+ defer pp.include_depth -= 1;
+ if (pp.include_depth > max_include_depth) {
+ try pp.comp.diag.add(.{
+ .tag = .too_many_includes,
+ .loc = .{ .id = first.source, .byte_offset = first.start, .line = first.line },
+ }, &.{});
+ return error.StopPreprocessing;
+ }
+
+ if (pp.include_guards.get(new_source.id)) |guard| {
+ if (pp.defines.contains(guard)) return;
+ }
+
+ if (pp.verbose) {
+ pp.verboseLog(first, "include file {s}", .{new_source.path});
+ }
+
+ _ = pp.preprocessExtra(new_source) catch |er| switch (er) {
+ error.StopPreprocessing => {},
+ else => |e| return e,
+ };
+}
+
+/// tokens that are part of a pragma directive can happen in 3 ways:
+/// 1. directly in the text via `#pragma ...`
+/// 2. Via a string literal argument to `_Pragma`
+/// 3. Via a stringified macro argument which is used as an argument to `_Pragma`
+/// operator_loc: Location of `_Pragma`; null if this is from #pragma
+/// arg_locs: expansion locations of the argument to _Pragma. empty if #pragma or a raw string literal was used
+fn makePragmaToken(pp: *Preprocessor, raw: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !Token {
+ var tok = tokFromRaw(raw);
+ if (operator_loc) |loc| {
+ try tok.addExpansionLocation(pp.gpa, &.{loc});
+ }
+ try tok.addExpansionLocation(pp.gpa, arg_locs);
+ return tok;
+}
+
+/// Handle a pragma directive
+fn pragma(pp: *Preprocessor, tokenizer: *Tokenizer, pragma_tok: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !void {
+ const name_tok = tokenizer.nextNoWS();
+ if (name_tok.id == .nl or name_tok.id == .eof) return;
+
+ const name = pp.tokSlice(name_tok);
+ try pp.tokens.append(pp.gpa, try pp.makePragmaToken(pragma_tok, operator_loc, arg_locs));
+ const pragma_start: u32 = @intCast(pp.tokens.len);
+
+ const pragma_name_tok = try pp.makePragmaToken(name_tok, operator_loc, arg_locs);
+ try pp.tokens.append(pp.gpa, pragma_name_tok);
+ while (true) {
+ const next_tok = tokenizer.next();
+ if (next_tok.id == .whitespace) continue;
+ if (next_tok.id == .eof) {
+ try pp.tokens.append(pp.gpa, .{
+ .id = .nl,
+ .loc = .{ .id = .generated },
+ });
+ break;
+ }
+ try pp.tokens.append(pp.gpa, try pp.makePragmaToken(next_tok, operator_loc, arg_locs));
+ if (next_tok.id == .nl) break;
+ }
+ if (pp.comp.getPragma(name)) |prag| unknown: {
+ return prag.preprocessorCB(pp, pragma_start) catch |er| switch (er) {
+ error.UnknownPragma => break :unknown,
+ else => |e| return e,
+ };
+ }
+ return pp.comp.diag.add(.{
+ .tag = .unknown_pragma,
+ .loc = pragma_name_tok.loc,
+ }, pragma_name_tok.expansionSlice());
+}
+
+fn findIncludeFilenameToken(
+ pp: *Preprocessor,
+ first_token: RawToken,
+ tokenizer: *Tokenizer,
+ trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof },
+) !Token {
+ const start = pp.tokens.len;
+ defer pp.tokens.len = start;
+ var first = first_token;
+
+ if (first.id == .angle_bracket_left) to_end: {
+ // The tokenizer does not handle <foo> include strings so do it here.
+ while (tokenizer.index < tokenizer.buf.len) : (tokenizer.index += 1) {
+ switch (tokenizer.buf[tokenizer.index]) {
+ '>' => {
+ tokenizer.index += 1;
+ first.end = tokenizer.index;
+ first.id = .macro_string;
+ break :to_end;
+ },
+ '\n' => break,
+ else => {},
+ }
+ }
+ try pp.comp.diag.add(.{
+ .tag = .header_str_closing,
+ .loc = .{ .id = first.source, .byte_offset = tokenizer.index, .line = first.line },
+ }, &.{});
+ try pp.err(first, .header_str_match);
+ }
+ // Try to expand if the argument is a macro.
+ try pp.expandMacro(tokenizer, first);
+
+ // Check that we actually got a string.
+ const filename_tok = pp.tokens.get(start);
+ switch (filename_tok.id) {
+ .string_literal, .macro_string => {},
+ else => {
+ try pp.err(first, .expected_filename);
+ try pp.expectNl(tokenizer);
+ return error.InvalidInclude;
+ },
+ }
+ switch (trailing_token_behavior) {
+ .expect_nl_eof => {
+ // Error on extra tokens.
+ const nl = tokenizer.nextNoWS();
+ if ((nl.id != .nl and nl.id != .eof) or pp.tokens.len > start + 1) {
+ skipToNl(tokenizer);
+ try pp.err(first, .extra_tokens_directive_end);
+ }
+ },
+ .ignore_trailing_tokens => {},
+ }
+ return filename_tok;
+}
+
+fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source {
+ const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof);
+
+ // Check for empty filename.
+ const tok_slice = pp.expandedSlice(filename_tok);
+ if (tok_slice.len < 3) {
+ try pp.err(first, .empty_filename);
+ return error.InvalidInclude;
+ }
+
+ // Find the file.
+ const filename = tok_slice[1 .. tok_slice.len - 1];
+ const include_type: Compilation.IncludeType = switch (filename_tok.id) {
+ .string_literal => .quotes,
+ .macro_string => .angle_brackets,
+ else => unreachable,
+ };
+
+ return (try pp.comp.findInclude(filename, first.source, include_type, which)) orelse
+ pp.fatal(first, "'{s}' not found", .{filename});
+}
+
+/// Pretty print tokens and try to preserve whitespace.
+pub fn prettyPrintTokens(pp: *Preprocessor, w: anytype) !void {
+ var i: u32 = 0;
+ while (true) : (i += 1) {
+ var cur: Token = pp.tokens.get(i);
+ switch (cur.id) {
+ .eof => {
+ if (pp.tokens.len > 1 and pp.tokens.items(.id)[i - 1] != .nl) try w.writeByte('\n');
+ break;
+ },
+ .nl => try w.writeAll("\n"),
+ .keyword_pragma => {
+ const pragma_name = pp.expandedSlice(pp.tokens.get(i + 1));
+ const end_idx = mem.indexOfScalarPos(Token.Id, pp.tokens.items(.id), i, .nl) orelse i + 1;
+ const pragma_len = @as(u32, @intCast(end_idx)) - i;
+
+ if (pp.comp.getPragma(pragma_name)) |prag| {
+ if (!prag.shouldPreserveTokens(pp, i + 1)) {
+ i += pragma_len;
+ cur = pp.tokens.get(i);
+ continue;
+ }
+ }
+ try w.writeAll("#pragma");
+ i += 1;
+ while (true) : (i += 1) {
+ cur = pp.tokens.get(i);
+ if (cur.id == .nl) {
+ try w.writeByte('\n');
+ break;
+ }
+ try w.writeByte(' ');
+ const slice = pp.expandedSlice(cur);
+ try w.writeAll(slice);
+ }
+ },
+ .whitespace => {
+ var slice = pp.expandedSlice(cur);
+ while (mem.indexOfScalar(u8, slice, '\n')) |some| {
+ try w.writeByte('\n');
+ slice = slice[some + 1 ..];
+ }
+ for (slice) |_| try w.writeByte(' ');
+ },
+ else => {
+ const slice = pp.expandedSlice(cur);
+ try w.writeAll(slice);
+ },
+ }
+ }
+}
+
+test "Preserve pragma tokens sometimes" {
+ const allocator = std.testing.allocator;
+ const Test = struct {
+ fn runPreprocessor(source_text: []const u8) ![]const u8 {
+ var buf = std.ArrayList(u8).init(allocator);
+ defer buf.deinit();
+
+ var comp = Compilation.init(allocator);
+ defer comp.deinit();
+
+ try comp.addDefaultPragmaHandlers();
+
+ var pp = Preprocessor.init(&comp);
+ defer pp.deinit();
+
+ pp.preserve_whitespace = true;
+
+ const test_runner_macros = try comp.addSourceFromBuffer("<test_runner>", source_text);
+ const eof = try pp.preprocess(test_runner_macros);
+ try pp.tokens.append(pp.gpa, eof);
+ try pp.prettyPrintTokens(buf.writer());
+ return allocator.dupe(u8, buf.items);
+ }
+
+ fn check(source_text: []const u8, expected: []const u8) !void {
+ const output = try runPreprocessor(source_text);
+ defer allocator.free(output);
+
+ try std.testing.expectEqualStrings(expected, output);
+ }
+ };
+ const preserve_gcc_diagnostic =
+ \\#pragma GCC diagnostic error "-Wnewline-eof"
+ \\#pragma GCC warning error "-Wnewline-eof"
+ \\int x;
+ \\#pragma GCC ignored error "-Wnewline-eof"
+ \\
+ ;
+ try Test.check(preserve_gcc_diagnostic, preserve_gcc_diagnostic);
+
+ const omit_once =
+ \\#pragma once
+ \\int x;
+ \\#pragma once
+ \\
+ ;
+ try Test.check(omit_once, "int x;\n");
+
+ const omit_poison =
+ \\#pragma GCC poison foobar
+ \\
+ ;
+ try Test.check(omit_poison, "");
+}
+
+test "destringify" {
+ const allocator = std.testing.allocator;
+ const Test = struct {
+ fn testDestringify(pp: *Preprocessor, stringified: []const u8, destringified: []const u8) !void {
+ pp.char_buf.clearRetainingCapacity();
+ try pp.char_buf.ensureUnusedCapacity(stringified.len);
+ pp.destringify(stringified);
+ try std.testing.expectEqualStrings(destringified, pp.char_buf.items);
+ }
+ };
+ var comp = Compilation.init(allocator);
+ defer comp.deinit();
+ var pp = Preprocessor.init(&comp);
+ defer pp.deinit();
+
+ try Test.testDestringify(&pp, "hello\tworld\n", "hello\tworld\n");
+ try Test.testDestringify(&pp,
+ \\ \"FOO BAR BAZ\"
+ ,
+ \\ "FOO BAR BAZ"
+ );
+ try Test.testDestringify(&pp,
+ \\ \\t\\n
+ \\
+ ,
+ \\ \t\n
+ \\
+ );
+}
+
+test "Include guards" {
+ const Test = struct {
+ /// This is here so that when #elifdef / #elifndef are added we don't forget
+ /// to test that they don't accidentally break include guard detection
+ fn pairsWithIfndef(tok_id: RawToken.Id) bool {
+ return switch (tok_id) {
+ .keyword_elif,
+ .keyword_elifdef,
+ .keyword_elifndef,
+ .keyword_else,
+ => true,
+
+ .keyword_include,
+ .keyword_include_next,
+ .keyword_embed,
+ .keyword_define,
+ .keyword_defined,
+ .keyword_undef,
+ .keyword_ifdef,
+ .keyword_ifndef,
+ .keyword_error,
+ .keyword_warning,
+ .keyword_pragma,
+ .keyword_line,
+ .keyword_endif,
+ => false,
+ else => unreachable,
+ };
+ }
+
+ fn skippable(tok_id: RawToken.Id) bool {
+ return switch (tok_id) {
+ .keyword_defined, .keyword_va_args, .keyword_endif => true,
+ else => false,
+ };
+ }
+
+ fn testIncludeGuard(allocator: std.mem.Allocator, comptime template: []const u8, tok_id: RawToken.Id, expected_guards: u32) !void {
+ var comp = Compilation.init(allocator);
+ defer comp.deinit();
+ var pp = Preprocessor.init(&comp);
+ defer pp.deinit();
+
+ const path = try std.fs.path.join(allocator, &.{ ".", "bar.h" });
+ defer allocator.free(path);
+
+ _ = try comp.addSourceFromBuffer(path, "int bar = 5;\n");
+
+ var buf = std.ArrayList(u8).init(allocator);
+ defer buf.deinit();
+
+ var writer = buf.writer();
+ switch (tok_id) {
+ .keyword_include, .keyword_include_next => try writer.print(template, .{ tok_id.lexeme().?, " \"bar.h\"" }),
+ .keyword_define, .keyword_undef => try writer.print(template, .{ tok_id.lexeme().?, " BAR" }),
+ .keyword_ifndef,
+ .keyword_ifdef,
+ .keyword_elifdef,
+ .keyword_elifndef,
+ => try writer.print(template, .{ tok_id.lexeme().?, " BAR\n#endif" }),
+ else => try writer.print(template, .{ tok_id.lexeme().?, "" }),
+ }
+ const source = try comp.addSourceFromBuffer("test.h", buf.items);
+ _ = try pp.preprocess(source);
+
+ try std.testing.expectEqual(expected_guards, pp.include_guards.count());
+ }
+ };
+ const tags = std.meta.tags(RawToken.Id);
+ for (tags) |tag| {
+ if (Test.skippable(tag)) continue;
+ var copy = tag;
+ copy.simplifyMacroKeyword();
+ if (copy != tag or tag == .keyword_else) {
+ const inside_ifndef_template =
+ \\//Leading comment (should be ignored)
+ \\
+ \\#ifndef FOO
+ \\#{s}{s}
+ \\#endif
+ ;
+ const expected_guards: u32 = if (Test.pairsWithIfndef(tag)) 0 else 1;
+ try Test.testIncludeGuard(std.testing.allocator, inside_ifndef_template, tag, expected_guards);
+
+ const outside_ifndef_template =
+ \\#ifndef FOO
+ \\#endif
+ \\#{s}{s}
+ ;
+ try Test.testIncludeGuard(std.testing.allocator, outside_ifndef_template, tag, 0);
+ }
+ }
+}
deps/aro/record_layout.zig
@@ -0,0 +1,669 @@
+//! Record layout code adapted from https://github.com/mahkoh/repr-c
+//! Licensed under MIT license: https://github.com/mahkoh/repr-c/tree/master/repc/facade
+
+const std = @import("std");
+const Type = @import("Type.zig");
+const Attribute = @import("Attribute.zig");
+const Compilation = @import("Compilation.zig");
+const Parser = @import("Parser.zig");
+const Record = Type.Record;
+const Field = Record.Field;
+const TypeLayout = Type.TypeLayout;
+const FieldLayout = Type.FieldLayout;
+const target_util = @import("target.zig");
+
+const BITS_PER_BYTE = 8;
+
+const OngoingBitfield = struct {
+ size_bits: u64,
+ unused_size_bits: u64,
+};
+
+const SysVContext = struct {
+ /// Does the record have an __attribute__((packed)) annotation.
+ attr_packed: bool,
+ /// The value of #pragma pack(N) at the type level if any.
+ max_field_align_bits: ?u64,
+ /// The alignment of this record.
+ aligned_bits: u32,
+ is_union: bool,
+ /// The size of the record. This might not be a multiple of 8 if the record contains bit-fields.
+ /// For structs, this is also the offset of the first bit after the last field.
+ size_bits: u64,
+ /// non-null if the previous field was a non-zero-sized bit-field. Only used by MinGW.
+ ongoing_bitfield: ?OngoingBitfield,
+
+ comp: *const Compilation,
+
+ fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) SysVContext {
+ var pack_value: ?u64 = null;
+ if (pragma_pack) |pak| {
+ pack_value = pak * BITS_PER_BYTE;
+ }
+ var req_align: u29 = BITS_PER_BYTE;
+ if (ty.requestedAlignment(comp)) |aln| {
+ req_align = aln * BITS_PER_BYTE;
+ }
+ return SysVContext{
+ .attr_packed = ty.hasAttribute(.@"packed"),
+ .max_field_align_bits = pack_value,
+ .aligned_bits = req_align,
+ .is_union = ty.is(.@"union"),
+ .size_bits = 0,
+ .comp = comp,
+ .ongoing_bitfield = null,
+ };
+ }
+
+ fn layoutFields(self: *SysVContext, rec: *const Record) void {
+ for (rec.fields, 0..) |*fld, fld_indx| {
+ const type_layout = computeLayout(fld.ty, self.comp);
+
+ var field_attrs: ?[]const Attribute = null;
+ if (rec.field_attributes) |attrs| {
+ field_attrs = attrs[fld_indx];
+ }
+ if (self.comp.target.isMinGW()) {
+ fld.layout = self.layoutMinGWField(fld, field_attrs, type_layout);
+ } else {
+ if (fld.isRegularField()) {
+ fld.layout = self.layoutRegularField(field_attrs, type_layout);
+ } else {
+ fld.layout = self.layoutBitField(field_attrs, type_layout, fld.isNamed(), fld.specifiedBitWidth());
+ }
+ }
+ }
+ }
+
+ /// On MinGW the alignment of the field is calculated in the usual way except that the alignment of
+ /// the underlying type is ignored in three cases
+ /// - the field is packed
+ /// - the field is a bit-field and the previous field was a non-zero-sized bit-field with the same type size
+ /// - the field is a zero-sized bit-field and the previous field was not a non-zero-sized bit-field
+ /// See test case 0068.
+ fn ignoreTypeAlignment(is_attr_packed: bool, bit_width: ?u32, ongoing_bitfield: ?OngoingBitfield, fld_layout: TypeLayout) bool {
+ if (is_attr_packed) return true;
+ if (bit_width) |width| {
+ if (ongoing_bitfield) |ongoing| {
+ if (ongoing.size_bits == fld_layout.size_bits) return true;
+ } else {
+ if (width == 0) return true;
+ }
+ }
+ return false;
+ }
+
+ fn layoutMinGWField(
+ self: *SysVContext,
+ field: *const Field,
+ field_attrs: ?[]const Attribute,
+ field_layout: TypeLayout,
+ ) FieldLayout {
+ const annotation_alignment_bits = BITS_PER_BYTE * (Type.annotationAlignment(self.comp, field_attrs) orelse 1);
+ const is_attr_packed = self.attr_packed or isPacked(field_attrs);
+ const ignore_type_alignment = ignoreTypeAlignment(is_attr_packed, field.bit_width, self.ongoing_bitfield, field_layout);
+
+ var field_alignment_bits: u64 = field_layout.field_alignment_bits;
+ if (ignore_type_alignment) {
+ field_alignment_bits = BITS_PER_BYTE;
+ }
+ field_alignment_bits = @max(field_alignment_bits, annotation_alignment_bits);
+ if (self.max_field_align_bits) |bits| {
+ field_alignment_bits = @min(field_alignment_bits, bits);
+ }
+
+ // The field affects the record alignment in one of three cases
+ // - the field is a regular field
+ // - the field is a zero-width bit-field following a non-zero-width bit-field
+ // - the field is a non-zero-width bit-field and not packed.
+ // See test case 0069.
+ const update_record_alignment =
+ field.isRegularField() or
+ (field.specifiedBitWidth() == 0 and self.ongoing_bitfield != null) or
+ (field.specifiedBitWidth() != 0 and !is_attr_packed);
+
+ // If a field affects the alignment of a record, the alignment is calculated in the
+ // usual way except that __attribute__((packed)) is ignored on a zero-width bit-field.
+ // See test case 0068.
+ if (update_record_alignment) {
+ var ty_alignment_bits = field_layout.field_alignment_bits;
+ if (is_attr_packed and (field.isRegularField() or field.specifiedBitWidth() != 0)) {
+ ty_alignment_bits = BITS_PER_BYTE;
+ }
+ ty_alignment_bits = @max(ty_alignment_bits, annotation_alignment_bits);
+ if (self.max_field_align_bits) |bits| {
+ ty_alignment_bits = @intCast(@min(ty_alignment_bits, bits));
+ }
+ self.aligned_bits = @max(self.aligned_bits, ty_alignment_bits);
+ }
+
+ // NOTE: ty_alignment_bits and field_alignment_bits are different in the following case:
+ // Y = { size: 64, alignment: 64 }struct {
+ // { offset: 0, size: 1 }c { size: 8, alignment: 8 }char:1,
+ // @attr_packed _ { size: 64, alignment: 64 }long long:0,
+ // { offset: 8, size: 8 }d { size: 8, alignment: 8 }char,
+ // }
+ if (field.isRegularField()) {
+ return self.layoutRegularFieldMinGW(field_layout.size_bits, field_alignment_bits);
+ } else {
+ return self.layoutBitFieldMinGW(field_layout.size_bits, field_alignment_bits, field.isNamed(), field.specifiedBitWidth());
+ }
+ }
+
+ fn layoutBitFieldMinGW(
+ self: *SysVContext,
+ ty_size_bits: u64,
+ field_alignment_bits: u64,
+ is_named: bool,
+ width: u64,
+ ) FieldLayout {
+ std.debug.assert(width <= ty_size_bits); // validated in parser
+
+ // In a union, the size of the underlying type does not affect the size of the union.
+ // See test case 0070.
+ if (self.is_union) {
+ self.size_bits = @max(self.size_bits, width);
+ if (!is_named) return .{};
+ return .{
+ .offset_bits = 0,
+ .size_bits = width,
+ };
+ }
+ if (width == 0) {
+ self.ongoing_bitfield = null;
+ } else {
+ // If there is an ongoing bit-field in a struct whose underlying type has the same size and
+ // if there is enough space left to place this bit-field, then this bit-field is placed in
+ // the ongoing bit-field and the size of the struct is not affected by this
+ // bit-field. See test case 0037.
+ if (self.ongoing_bitfield) |*ongoing| {
+ if (ongoing.size_bits == ty_size_bits and ongoing.unused_size_bits >= width) {
+ const offset_bits = self.size_bits - ongoing.unused_size_bits;
+ ongoing.unused_size_bits -= width;
+ if (!is_named) return .{};
+ return .{
+ .offset_bits = offset_bits,
+ .size_bits = width,
+ };
+ }
+ }
+ // Otherwise this field is part of a new ongoing bit-field.
+ self.ongoing_bitfield = .{
+ .size_bits = ty_size_bits,
+ .unused_size_bits = ty_size_bits - width,
+ };
+ }
+ const offset_bits = std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
+ self.size_bits = if (width == 0) offset_bits else offset_bits + ty_size_bits;
+ if (!is_named) return .{};
+ return .{
+ .offset_bits = offset_bits,
+ .size_bits = width,
+ };
+ }
+
+ fn layoutRegularFieldMinGW(
+ self: *SysVContext,
+ ty_size_bits: u64,
+ field_alignment_bits: u64,
+ ) FieldLayout {
+ self.ongoing_bitfield = null;
+ // A struct field starts at the next offset in the struct that is properly
+ // aligned with respect to the start of the struct. See test case 0033.
+ // A union field always starts at offset 0.
+ const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
+
+ // Set the size of the record to the maximum of the current size and the end of
+ // the field. See test case 0034.
+ self.size_bits = @max(self.size_bits, offset_bits + ty_size_bits);
+
+ return .{
+ .offset_bits = offset_bits,
+ .size_bits = ty_size_bits,
+ };
+ }
+
+ fn layoutRegularField(
+ self: *SysVContext,
+ fld_attrs: ?[]const Attribute,
+ fld_layout: TypeLayout,
+ ) FieldLayout {
+ var fld_align_bits = fld_layout.field_alignment_bits;
+
+ // If the struct or the field is packed, then the alignment of the underlying type is
+ // ignored. See test case 0084.
+ if (self.attr_packed or isPacked(fld_attrs)) {
+ fld_align_bits = BITS_PER_BYTE;
+ }
+
+ // The field alignment can be increased by __attribute__((aligned)) annotations on the
+ // field. See test case 0085.
+ if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
+ fld_align_bits = @max(fld_align_bits, anno * BITS_PER_BYTE);
+ }
+
+ // #pragma pack takes precedence over all other attributes. See test cases 0084 and
+ // 0085.
+ if (self.max_field_align_bits) |req_bits| {
+ fld_align_bits = @intCast(@min(fld_align_bits, req_bits));
+ }
+
+ // A struct field starts at the next offset in the struct that is properly
+ // aligned with respect to the start of the struct.
+ const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, fld_align_bits);
+ const size_bits = fld_layout.size_bits;
+
+ // The alignment of a record is the maximum of its field alignments. See test cases
+ // 0084, 0085, 0086.
+ self.size_bits = @max(self.size_bits, offset_bits + size_bits);
+ self.aligned_bits = @max(self.aligned_bits, fld_align_bits);
+
+ return .{
+ .offset_bits = offset_bits,
+ .size_bits = size_bits,
+ };
+ }
+
+ fn layoutBitField(
+ self: *SysVContext,
+ fld_attrs: ?[]const Attribute,
+ fld_layout: TypeLayout,
+ is_named: bool,
+ bit_width: u64,
+ ) FieldLayout {
+ const ty_size_bits = fld_layout.size_bits;
+ var ty_fld_algn_bits: u32 = fld_layout.field_alignment_bits;
+
+ if (bit_width > 0) {
+ std.debug.assert(bit_width <= ty_size_bits); // Checked in parser
+ // Some targets ignore the alignment of the underlying type when laying out
+ // non-zero-sized bit-fields. See test case 0072. On such targets, bit-fields never
+ // cross a storage boundary. See test case 0081.
+ if (target_util.ignoreNonZeroSizedBitfieldTypeAlignment(self.comp.target)) {
+ ty_fld_algn_bits = 1;
+ }
+ } else {
+ // Some targets ignore the alignment of the underlying type when laying out
+ // zero-sized bit-fields. See test case 0073.
+ if (target_util.ignoreZeroSizedBitfieldTypeAlignment(self.comp.target)) {
+ ty_fld_algn_bits = 1;
+ }
+ // Some targets have a minimum alignment of zero-sized bit-fields. See test case
+ // 0074.
+ if (target_util.minZeroWidthBitfieldAlignment(self.comp.target)) |target_align| {
+ ty_fld_algn_bits = @max(ty_fld_algn_bits, target_align);
+ }
+ }
+
+ // __attribute__((packed)) on the record is identical to __attribute__((packed)) on each
+ // field. See test case 0067.
+ const attr_packed = self.attr_packed or isPacked(fld_attrs);
+ const has_packing_annotation = attr_packed or self.max_field_align_bits != null;
+
+ const annotation_alignment: u32 = if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| anno * BITS_PER_BYTE else 1;
+
+ const first_unused_bit: u64 = if (self.is_union) 0 else self.size_bits;
+ var field_align_bits: u64 = 1;
+
+ if (bit_width == 0) {
+ field_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+ } else if (self.comp.langopts.emulate == .gcc) {
+ // On GCC, the field alignment is at least the alignment requested by annotations
+ // except as restricted by #pragma pack. See test case 0083.
+ field_align_bits = annotation_alignment;
+ if (self.max_field_align_bits) |max_bits| {
+ field_align_bits = @min(annotation_alignment, max_bits);
+ }
+
+ // On GCC, if there are no packing annotations and
+ // - the field would otherwise start at an offset such that it would cross a
+ // storage boundary or
+ // - the alignment of the type is larger than its size,
+ // then it is aligned to the type's field alignment. See test case 0083.
+ if (!has_packing_annotation) {
+ const start_bit = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
+
+ const does_field_cross_boundary = start_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
+
+ if (ty_fld_algn_bits > ty_size_bits or does_field_cross_boundary) {
+ field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
+ }
+ }
+ } else {
+ std.debug.assert(self.comp.langopts.emulate == .clang);
+
+ // On Clang, the alignment requested by annotations is not respected if it is
+ // larger than the value of #pragma pack. See test case 0083.
+ if (annotation_alignment <= self.max_field_align_bits orelse std.math.maxInt(u29)) {
+ field_align_bits = @max(field_align_bits, annotation_alignment);
+ }
+ // On Clang, if there are no packing annotations and the field would cross a
+ // storage boundary if it were positioned at the first unused bit in the record,
+ // it is aligned to the type's field alignment. See test case 0083.
+ if (!has_packing_annotation) {
+ const does_field_cross_boundary = first_unused_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
+
+ if (does_field_cross_boundary)
+ field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
+ }
+ }
+
+ const offset_bits = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
+ self.size_bits = @max(self.size_bits, offset_bits + bit_width);
+
+ // Unnamed fields do not contribute to the record alignment except on a few targets.
+ // See test case 0079.
+ if (is_named or target_util.unnamedFieldAffectsAlignment(self.comp.target)) {
+ var inherited_align_bits: u32 = undefined;
+
+ if (bit_width == 0) {
+ // If the width is 0, #pragma pack and __attribute__((packed)) are ignored.
+ // See test case 0075.
+ inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+ } else if (self.max_field_align_bits) |max_align_bits| {
+ // Otherwise, if a #pragma pack is in effect, __attribute__((packed)) on the field or
+ // record is ignored. See test case 0076.
+ inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+ inherited_align_bits = @intCast(@min(inherited_align_bits, max_align_bits));
+ } else if (attr_packed) {
+ // Otherwise, if the field or the record is packed, the field alignment is 1 bit unless
+ // it is explicitly increased with __attribute__((aligned)). See test case 0077.
+ inherited_align_bits = annotation_alignment;
+ } else {
+ // Otherwise, the field alignment is the field alignment of the underlying type unless
+ // it is explicitly increased with __attribute__((aligned)). See test case 0078.
+ inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+ }
+ self.aligned_bits = @max(self.aligned_bits, inherited_align_bits);
+ }
+
+ if (!is_named) return .{};
+ return .{
+ .size_bits = bit_width,
+ .offset_bits = offset_bits,
+ };
+ }
+};
+
+const MsvcContext = struct {
+ req_align_bits: u32,
+ max_field_align_bits: ?u32,
+ /// The alignment of pointers that point to an object of this type. This is greater than or equal
+ /// to the required alignment. Once all fields have been laid out, the size of the record will be
+ /// rounded up to this value.
+ pointer_align_bits: u32,
+ /// The alignment of this type when it is used as a record field. This is greater than or equal to
+ /// the pointer alignment.
+ field_align_bits: u32,
+ size_bits: u64,
+ ongoing_bitfield: ?OngoingBitfield,
+ contains_non_bitfield: bool,
+ is_union: bool,
+ comp: *const Compilation,
+
+ fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) MsvcContext {
+ var pack_value: ?u32 = null;
+ if (ty.hasAttribute(.@"packed")) {
+ // __attribute__((packed)) behaves like #pragma pack(1) in clang. See test case 0056.
+ pack_value = BITS_PER_BYTE;
+ }
+ if (pack_value == null) {
+ if (pragma_pack) |pack| {
+ pack_value = pack * BITS_PER_BYTE;
+ }
+ }
+ if (pack_value) |pack| {
+ pack_value = msvcPragmaPack(comp, pack);
+ }
+
+ // The required alignment can be increased by adding a __declspec(align)
+ // annotation. See test case 0023.
+ var must_align: u29 = BITS_PER_BYTE;
+ if (ty.requestedAlignment(comp)) |req_align| {
+ must_align = req_align * BITS_PER_BYTE;
+ }
+ return MsvcContext{
+ .req_align_bits = must_align,
+ .pointer_align_bits = must_align,
+ .field_align_bits = must_align,
+ .size_bits = 0,
+ .max_field_align_bits = pack_value,
+ .ongoing_bitfield = null,
+ .contains_non_bitfield = false,
+ .is_union = ty.is(.@"union"),
+ .comp = comp,
+ };
+ }
+
+ fn layoutField(self: *MsvcContext, fld: *const Field, fld_attrs: ?[]const Attribute) FieldLayout {
+ const type_layout = computeLayout(fld.ty, self.comp);
+
+ // The required alignment of the field is the maximum of the required alignment of the
+ // underlying type and the __declspec(align) annotation on the field itself.
+ // See test case 0028.
+ var req_align = type_layout.required_alignment_bits;
+ if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
+ req_align = @max(anno * BITS_PER_BYTE, req_align);
+ }
+
+ // The required alignment of a record is the maximum of the required alignments of its
+ // fields except that the required alignment of bitfields is ignored.
+ // See test case 0029.
+ if (fld.isRegularField()) {
+ self.req_align_bits = @max(self.req_align_bits, req_align);
+ }
+
+ // The offset of the field is based on the field alignment of the underlying type.
+ // See test case 0027.
+ var fld_align_bits = type_layout.field_alignment_bits;
+ if (self.max_field_align_bits) |max_align| {
+ fld_align_bits = @min(fld_align_bits, max_align);
+ }
+ // check the requested alignment of the field type.
+ if (fld.ty.requestedAlignment(self.comp)) |type_req_align| {
+ fld_align_bits = @max(fld_align_bits, type_req_align * 8);
+ }
+
+ if (isPacked(fld_attrs)) {
+ // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
+ // pack(1) had been applied only to this field. See test case 0057.
+ fld_align_bits = BITS_PER_BYTE;
+ }
+ // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
+ // pack(1) had been applied only to this field. See test case 0057.
+ fld_align_bits = @max(fld_align_bits, req_align);
+ if (fld.isRegularField()) {
+ return self.layoutRegularField(type_layout.size_bits, fld_align_bits);
+ } else {
+ return self.layoutBitField(type_layout.size_bits, fld_align_bits, fld.specifiedBitWidth());
+ }
+ }
+
+ fn layoutBitField(self: *MsvcContext, ty_size_bits: u64, field_align: u32, bit_width: u32) FieldLayout {
+ if (bit_width == 0) {
+ // A zero-sized bit-field that does not follow a non-zero-sized bit-field does not affect
+ // the overall layout of the record. Even in a union where the order would otherwise
+ // not matter. See test case 0035.
+ if (self.ongoing_bitfield) |_| {
+ self.ongoing_bitfield = null;
+ } else {
+ // this field takes 0 space.
+ return .{ .offset_bits = self.size_bits, .size_bits = bit_width };
+ }
+ } else {
+ std.debug.assert(bit_width <= ty_size_bits);
+ // If there is an ongoing bit-field in a struct whose underlying type has the same size and
+ // if there is enough space left to place this bit-field, then this bit-field is placed in
+ // the ongoing bit-field and the overall layout of the struct is not affected by this
+ // bit-field. See test case 0037.
+ if (!self.is_union) {
+ if (self.ongoing_bitfield) |*p| {
+ if (p.size_bits == ty_size_bits and p.unused_size_bits >= bit_width) {
+ const offset_bits = self.size_bits - p.unused_size_bits;
+ p.unused_size_bits -= bit_width;
+ return .{ .offset_bits = offset_bits, .size_bits = bit_width };
+ }
+ }
+ }
+ // Otherwise this field is part of a new ongoing bit-field.
+ self.ongoing_bitfield = .{ .size_bits = ty_size_bits, .unused_size_bits = ty_size_bits - bit_width };
+ }
+ const offset_bits = if (!self.is_union) bits: {
+ // This is the one place in the layout of a record where the pointer alignment might
+ // get assigned a smaller value than the field alignment. This can only happen if
+ // the field or the type of the field has a required alignment. Otherwise the value
+ // of field_alignment_bits is already bound by max_field_alignment_bits.
+ // See test case 0038.
+ const p_align = if (self.max_field_align_bits) |max_fld_align|
+ @min(max_fld_align, field_align)
+ else
+ field_align;
+ self.pointer_align_bits = @max(self.pointer_align_bits, p_align);
+ self.field_align_bits = @max(self.field_align_bits, field_align);
+
+ const offset_bits = std.mem.alignForward(u64, self.size_bits, field_align);
+ self.size_bits = if (bit_width == 0) offset_bits else offset_bits + ty_size_bits;
+
+ break :bits offset_bits;
+ } else bits: {
+ // Bit-fields do not affect the alignment of a union. See test case 0041.
+ self.size_bits = @max(self.size_bits, ty_size_bits);
+ break :bits 0;
+ };
+ return .{ .offset_bits = offset_bits, .size_bits = bit_width };
+ }
+
+ fn layoutRegularField(self: *MsvcContext, size_bits: u64, field_align: u32) FieldLayout {
+ self.contains_non_bitfield = true;
+ self.ongoing_bitfield = null;
+ // The alignment of the field affects both the pointer alignment and the field
+ // alignment of the record. See test case 0032.
+ self.pointer_align_bits = @max(self.pointer_align_bits, field_align);
+ self.field_align_bits = @max(self.field_align_bits, field_align);
+ const offset_bits = switch (self.is_union) {
+ true => 0,
+ false => std.mem.alignForward(u64, self.size_bits, field_align),
+ };
+ self.size_bits = @max(self.size_bits, offset_bits + size_bits);
+ return .{ .offset_bits = offset_bits, .size_bits = size_bits };
+ }
+ fn handleZeroSizedRecord(self: *MsvcContext) void {
+ if (self.is_union) {
+ // MSVC does not allow unions without fields.
+ // If all fields in a union have size 0, the size of the union is set to
+ // - its field alignment if it contains at least one non-bitfield
+ // - 4 bytes if it contains only bitfields
+ // See test case 0025.
+ if (self.contains_non_bitfield) {
+ self.size_bits = self.field_align_bits;
+ } else {
+ self.size_bits = 4 * BITS_PER_BYTE;
+ }
+ } else {
+ // If all fields in a struct have size 0, its size is set to its required alignment
+ // but at least to 4 bytes. See test case 0026.
+ self.size_bits = @max(self.req_align_bits, 4 * BITS_PER_BYTE);
+ self.pointer_align_bits = @intCast(@min(self.pointer_align_bits, self.size_bits));
+ }
+ }
+};
+
+pub fn compute(rec: *Type.Record, ty: Type, comp: *const Compilation, pragma_pack: ?u8) void {
+ switch (comp.langopts.emulate) {
+ .gcc, .clang => {
+ var context = SysVContext.init(ty, comp, pragma_pack);
+
+ context.layoutFields(rec);
+
+ context.size_bits = std.mem.alignForward(u64, context.size_bits, context.aligned_bits);
+
+ rec.type_layout = .{
+ .size_bits = context.size_bits,
+ .field_alignment_bits = context.aligned_bits,
+ .pointer_alignment_bits = context.aligned_bits,
+ .required_alignment_bits = BITS_PER_BYTE,
+ };
+ },
+ .msvc => {
+ var context = MsvcContext.init(ty, comp, pragma_pack);
+ for (rec.fields, 0..) |*fld, fld_indx| {
+ var field_attrs: ?[]const Attribute = null;
+ if (rec.field_attributes) |attrs| {
+ field_attrs = attrs[fld_indx];
+ }
+
+ fld.layout = context.layoutField(fld, field_attrs);
+ }
+ if (context.size_bits == 0) {
+ // As an extension, MSVC allows records that only contain zero-sized bitfields and empty
+ // arrays. Such records would be zero-sized but this case is handled here separately to
+ // ensure that there are no zero-sized records.
+ context.handleZeroSizedRecord();
+ }
+ context.size_bits = std.mem.alignForward(u64, context.size_bits, context.pointer_align_bits);
+ rec.type_layout = .{
+ .size_bits = context.size_bits,
+ .field_alignment_bits = context.field_align_bits,
+ .pointer_alignment_bits = context.pointer_align_bits,
+ .required_alignment_bits = context.req_align_bits,
+ };
+ },
+ }
+}
+
+fn computeLayout(ty: Type, comp: *const Compilation) TypeLayout {
+ if (ty.getRecord()) |rec| {
+ const requested = BITS_PER_BYTE * (ty.requestedAlignment(comp) orelse 0);
+ return .{
+ .size_bits = rec.type_layout.size_bits,
+ .pointer_alignment_bits = @max(requested, rec.type_layout.pointer_alignment_bits),
+ .field_alignment_bits = @max(requested, rec.type_layout.field_alignment_bits),
+ .required_alignment_bits = rec.type_layout.required_alignment_bits,
+ };
+ } else {
+ const type_align = ty.alignof(comp) * BITS_PER_BYTE;
+ return .{
+ .size_bits = ty.bitSizeof(comp) orelse 0,
+ .pointer_alignment_bits = type_align,
+ .field_alignment_bits = type_align,
+ .required_alignment_bits = BITS_PER_BYTE,
+ };
+ }
+}
+
+fn isPacked(attrs: ?[]const Attribute) bool {
+ const a = attrs orelse return false;
+
+ for (a) |attribute| {
+ if (attribute.tag != .@"packed") continue;
+ return true;
+ }
+ return false;
+}
+
+// The effect of #pragma pack(N) depends on the target.
+//
+// x86: By default, there is no maximum field alignment. N={1,2,4} set the maximum field
+// alignment to that value. All other N activate the default.
+// x64: By default, there is no maximum field alignment. N={1,2,4,8} set the maximum field
+// alignment to that value. All other N activate the default.
+// arm: By default, the maximum field alignment is 8. N={1,2,4,8,16} set the maximum field
+// alignment to that value. All other N activate the default.
+// arm64: By default, the maximum field alignment is 8. N={1,2,4,8} set the maximum field
+// alignment to that value. N=16 disables the maximum field alignment. All other N
+// activate the default.
+//
+// See test case 0020.
+pub fn msvcPragmaPack(comp: *const Compilation, pack: u32) ?u32 {
+ return switch (pack) {
+ 8, 16, 32 => pack,
+ 64 => if (comp.target.cpu.arch == .x86) null else pack,
+ 128 => if (comp.target.cpu.arch == .thumb) pack else null,
+ else => {
+ return switch (comp.target.cpu.arch) {
+ .thumb, .aarch64 => 64,
+ else => null,
+ };
+ },
+ };
+}
deps/aro/Source.zig
@@ -0,0 +1,125 @@
+const std = @import("std");
+const Source = @This();
+
+pub const Id = enum(u32) {
+ unused = 0,
+ generated = 1,
+ _,
+};
+
+pub const Location = struct {
+ id: Id = .unused,
+ byte_offset: u32 = 0,
+ line: u32 = 0,
+
+ pub fn eql(a: Location, b: Location) bool {
+ return a.id == b.id and a.byte_offset == b.byte_offset and a.line == b.line;
+ }
+};
+
+path: []const u8,
+buf: []const u8,
+id: Id,
+/// each entry represents a byte position within `buf` where a backslash+newline was deleted
+/// from the original raw buffer. The same position can appear multiple times if multiple
+/// consecutive splices happened. Guaranteed to be non-decreasing
+splice_locs: []const u32,
+
+/// Todo: binary search instead of scanning entire `splice_locs`.
+pub fn numSplicesBefore(source: Source, byte_offset: u32) u32 {
+ for (source.splice_locs, 0..) |splice_offset, i| {
+ if (splice_offset > byte_offset) return @intCast(i);
+ }
+ return @intCast(source.splice_locs.len);
+}
+
+/// Returns the actual line number (before newline splicing) of a Location
+/// This corresponds to what the user would actually see in their text editor
+pub fn physicalLine(source: Source, loc: Location) u32 {
+ return loc.line + source.numSplicesBefore(loc.byte_offset);
+}
+
+const LineCol = struct { line: []const u8, line_no: u32, col: u32, width: u32, end_with_splice: bool };
+
+pub fn lineCol(source: Source, loc: Location) LineCol {
+ var start: usize = 0;
+ // find the start of the line which is either a newline or a splice
+ if (std.mem.lastIndexOfScalar(u8, source.buf[0..loc.byte_offset], '\n')) |some| start = some + 1;
+ const splice_index: u32 = for (source.splice_locs, 0..) |splice_offset, i| {
+ if (splice_offset > start) {
+ if (splice_offset < loc.byte_offset) {
+ start = splice_offset;
+ break @as(u32, @intCast(i)) + 1;
+ }
+ break @intCast(i);
+ }
+ } else @intCast(source.splice_locs.len);
+ var i: usize = start;
+ var col: u32 = 1;
+ var width: u32 = 0;
+
+ while (i < loc.byte_offset) : (col += 1) { // TODO this is still incorrect, but better
+ const len = std.unicode.utf8ByteSequenceLength(source.buf[i]) catch unreachable;
+ const cp = std.unicode.utf8Decode(source.buf[i..][0..len]) catch unreachable;
+ width += codepointWidth(cp);
+ i += len;
+ }
+
+ // find the end of the line which is either a newline, EOF or a splice
+ var nl = source.buf.len;
+ var end_with_splice = false;
+ if (std.mem.indexOfScalar(u8, source.buf[start..], '\n')) |some| nl = some + start;
+ if (source.splice_locs.len > splice_index and nl > source.splice_locs[splice_index] and source.splice_locs[splice_index] > start) {
+ end_with_splice = true;
+ nl = source.splice_locs[splice_index];
+ }
+ return .{
+ .line = source.buf[start..nl],
+ .line_no = loc.line + splice_index,
+ .col = col,
+ .width = width,
+ .end_with_splice = end_with_splice,
+ };
+}
+
+fn codepointWidth(cp: u32) u32 {
+ return switch (cp) {
+ 0x1100...0x115F,
+ 0x2329,
+ 0x232A,
+ 0x2E80...0x303F,
+ 0x3040...0x3247,
+ 0x3250...0x4DBF,
+ 0x4E00...0xA4C6,
+ 0xA960...0xA97C,
+ 0xAC00...0xD7A3,
+ 0xF900...0xFAFF,
+ 0xFE10...0xFE19,
+ 0xFE30...0xFE6B,
+ 0xFF01...0xFF60,
+ 0xFFE0...0xFFE6,
+ 0x1B000...0x1B001,
+ 0x1F200...0x1F251,
+ 0x20000...0x3FFFD,
+ 0x1F300...0x1F5FF,
+ 0x1F900...0x1F9FF,
+ => 2,
+ else => 1,
+ };
+}
+
+/// Returns the first offset, if any, in buf where an invalid utf8 sequence
+/// is found. Code adapted from std.unicode.utf8ValidateSlice
+pub fn offsetOfInvalidUtf8(self: Source) ?u32 {
+ const buf = self.buf;
+ std.debug.assert(buf.len <= std.math.maxInt(u32));
+ var i: u32 = 0;
+ while (i < buf.len) {
+ if (std.unicode.utf8ByteSequenceLength(buf[i])) |cp_len| {
+ if (i + cp_len > buf.len) return i;
+ if (std.meta.isError(std.unicode.utf8Decode(buf[i .. i + cp_len]))) return i;
+ i += cp_len;
+ } else |_| return i;
+ }
+ return null;
+}
deps/aro/StringInterner.zig
@@ -0,0 +1,78 @@
+const std = @import("std");
+const mem = std.mem;
+
+const StringInterner = @This();
+
+const StringToIdMap = std.StringHashMapUnmanaged(StringId);
+
+pub const StringId = enum(u32) {
+ empty,
+ _,
+};
+
+pub const TypeMapper = struct {
+ const LookupSpeed = enum {
+ fast,
+ slow,
+ };
+
+ data: union(LookupSpeed) {
+ fast: []const []const u8,
+ slow: *const StringToIdMap,
+ },
+
+ pub fn lookup(self: TypeMapper, string_id: StringInterner.StringId) []const u8 {
+ if (string_id == .empty) return "";
+ switch (self.data) {
+ .fast => |arr| return arr[@intFromEnum(string_id)],
+ .slow => |map| {
+ var it = map.iterator();
+ while (it.next()) |entry| {
+ if (entry.value_ptr.* == string_id) return entry.key_ptr.*;
+ }
+ unreachable;
+ },
+ }
+ }
+
+ pub fn deinit(self: TypeMapper, allocator: mem.Allocator) void {
+ switch (self.data) {
+ .slow => {},
+ .fast => |arr| allocator.free(arr),
+ }
+ }
+};
+
+string_table: StringToIdMap = .{},
+next_id: StringId = @enumFromInt(@intFromEnum(StringId.empty) + 1),
+
+pub fn deinit(self: *StringInterner, allocator: mem.Allocator) void {
+ self.string_table.deinit(allocator);
+}
+
+pub fn intern(self: *StringInterner, allocator: mem.Allocator, str: []const u8) !StringId {
+ if (str.len == 0) return .empty;
+
+ const gop = try self.string_table.getOrPut(allocator, str);
+ if (gop.found_existing) return gop.value_ptr.*;
+
+ defer self.next_id = @enumFromInt(@intFromEnum(self.next_id) + 1);
+ gop.value_ptr.* = self.next_id;
+ return self.next_id;
+}
+
+/// deinit for the returned TypeMapper is a no-op and does not need to be called
+pub fn getSlowTypeMapper(self: *const StringInterner) TypeMapper {
+ return TypeMapper{ .data = .{ .slow = &self.string_table } };
+}
+
+/// Caller must call `deinit` on the returned TypeMapper
+pub fn getFastTypeMapper(self: *const StringInterner, allocator: mem.Allocator) !TypeMapper {
+ var strings = try allocator.alloc([]const u8, @intFromEnum(self.next_id));
+ var it = self.string_table.iterator();
+ strings[0] = "";
+ while (it.next()) |entry| {
+ strings[@intFromEnum(entry.value_ptr.*)] = entry.key_ptr.*;
+ }
+ return TypeMapper{ .data = .{ .fast = strings } };
+}
deps/aro/SymbolStack.zig
@@ -0,0 +1,375 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const assert = std.debug.assert;
+const Tree = @import("Tree.zig");
+const Token = Tree.Token;
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Parser = @import("Parser.zig");
+const Value = @import("Value.zig");
+const StringId = @import("StringInterner.zig").StringId;
+
+const SymbolStack = @This();
+
+pub const Symbol = struct {
+ name: StringId,
+ ty: Type,
+ tok: TokenIndex,
+ node: NodeIndex = .none,
+ kind: Kind,
+ val: Value,
+};
+
+pub const Kind = enum {
+ typedef,
+ @"struct",
+ @"union",
+ @"enum",
+ decl,
+ def,
+ enumeration,
+ constexpr,
+};
+
+syms: std.MultiArrayList(Symbol) = .{},
+scopes: std.ArrayListUnmanaged(u32) = .{},
+
+pub fn deinit(s: *SymbolStack, gpa: Allocator) void {
+ s.syms.deinit(gpa);
+ s.scopes.deinit(gpa);
+ s.* = undefined;
+}
+
+pub fn scopeEnd(s: SymbolStack) u32 {
+ if (s.scopes.items.len == 0) return 0;
+ return s.scopes.items[s.scopes.items.len - 1];
+}
+
+pub fn pushScope(s: *SymbolStack, p: *Parser) !void {
+ try s.scopes.append(p.pp.comp.gpa, @intCast(s.syms.len));
+}
+
+pub fn popScope(s: *SymbolStack) void {
+ s.syms.len = s.scopes.pop();
+}
+
+pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ var i = s.syms.len;
+ while (i > 0) {
+ i -= 1;
+ switch (kinds[i]) {
+ .typedef => if (names[i] == name) return s.syms.get(i),
+ .@"struct" => if (names[i] == name) {
+ if (no_type_yet) return null;
+ try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));
+ return s.syms.get(i);
+ },
+ .@"union" => if (names[i] == name) {
+ if (no_type_yet) return null;
+ try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));
+ return s.syms.get(i);
+ },
+ .@"enum" => if (names[i] == name) {
+ if (no_type_yet) return null;
+ try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok));
+ return s.syms.get(i);
+ },
+ .def, .decl, .constexpr => if (names[i] == name) return null,
+ else => {},
+ }
+ }
+ return null;
+}
+
+pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ var i = s.syms.len;
+ while (i > 0) {
+ i -= 1;
+ switch (kinds[i]) {
+ .def, .decl, .enumeration, .constexpr => if (names[i] == name) return s.syms.get(i),
+ else => {},
+ }
+ }
+ return null;
+}
+
+pub fn findTag(
+ s: *SymbolStack,
+ p: *Parser,
+ name: StringId,
+ kind: Token.Id,
+ name_tok: TokenIndex,
+ next_tok_id: Token.Id,
+) !?Symbol {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ // `tag Name;` should always result in a new type if in a new scope.
+ const end = if (next_tok_id == .semicolon) s.scopeEnd() else 0;
+ var i = s.syms.len;
+ while (i > end) {
+ i -= 1;
+ switch (kinds[i]) {
+ .@"enum" => if (names[i] == name) {
+ if (kind == .keyword_enum) return s.syms.get(i);
+ break;
+ },
+ .@"struct" => if (names[i] == name) {
+ if (kind == .keyword_struct) return s.syms.get(i);
+ break;
+ },
+ .@"union" => if (names[i] == name) {
+ if (kind == .keyword_union) return s.syms.get(i);
+ break;
+ },
+ else => {},
+ }
+ } else return null;
+
+ if (i < s.scopeEnd()) return null;
+ try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ return null;
+}
+
+pub fn defineTypedef(
+ s: *SymbolStack,
+ p: *Parser,
+ name: StringId,
+ ty: Type,
+ tok: TokenIndex,
+ node: NodeIndex,
+) !void {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ const end = s.scopeEnd();
+ var i = s.syms.len;
+ while (i > end) {
+ i -= 1;
+ switch (kinds[i]) {
+ .typedef => if (names[i] == name) {
+ const prev_ty = s.syms.items(.ty)[i];
+ if (ty.eql(prev_ty, p.pp.comp, true)) break;
+ try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev_ty));
+ const previous_tok = s.syms.items(.tok)[i];
+ if (previous_tok != 0) try p.errTok(.previous_definition, previous_tok);
+ break;
+ },
+ else => {},
+ }
+ }
+ try s.syms.append(p.pp.comp.gpa, .{
+ .kind = .typedef,
+ .name = name,
+ .tok = tok,
+ .ty = ty,
+ .node = node,
+ .val = .{},
+ });
+}
+
+pub fn defineSymbol(
+ s: *SymbolStack,
+ p: *Parser,
+ name: StringId,
+ ty: Type,
+ tok: TokenIndex,
+ node: NodeIndex,
+ val: Value,
+ constexpr: bool,
+) !void {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ const end = s.scopeEnd();
+ var i = s.syms.len;
+ while (i > end) {
+ i -= 1;
+ switch (kinds[i]) {
+ .enumeration => if (names[i] == name) {
+ try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ break;
+ },
+ .decl => if (names[i] == name) {
+ const prev_ty = s.syms.items(.ty)[i];
+ if (!ty.eql(prev_ty, p.pp.comp, true)) { // TODO adjusted equality check
+ try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ }
+ break;
+ },
+ .def, .constexpr => if (names[i] == name) {
+ try p.errStr(.redefinition, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ break;
+ },
+ else => {},
+ }
+ }
+ try s.syms.append(p.pp.comp.gpa, .{
+ .kind = if (constexpr) .constexpr else .def,
+ .name = name,
+ .tok = tok,
+ .ty = ty,
+ .node = node,
+ .val = val,
+ });
+}
+
+pub fn declareSymbol(
+ s: *SymbolStack,
+ p: *Parser,
+ name: StringId,
+ ty: Type,
+ tok: TokenIndex,
+ node: NodeIndex,
+) !void {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ const end = s.scopeEnd();
+ var i = s.syms.len;
+ while (i > end) {
+ i -= 1;
+ switch (kinds[i]) {
+ .enumeration => if (names[i] == name) {
+ try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ break;
+ },
+ .decl => if (names[i] == name) {
+ const prev_ty = s.syms.items(.ty)[i];
+ if (!ty.eql(prev_ty, p.pp.comp, true)) { // TODO adjusted equality check
+ try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ }
+ break;
+ },
+ .def, .constexpr => if (names[i] == name) {
+ const prev_ty = s.syms.items(.ty)[i];
+ if (!ty.eql(prev_ty, p.pp.comp, true)) { // TODO adjusted equality check
+ try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ break;
+ }
+ return;
+ },
+ else => {},
+ }
+ }
+ try s.syms.append(p.pp.comp.gpa, .{
+ .kind = .decl,
+ .name = name,
+ .tok = tok,
+ .ty = ty,
+ .node = node,
+ .val = .{},
+ });
+}
+
+pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ const end = s.scopeEnd();
+ var i = s.syms.len;
+ while (i > end) {
+ i -= 1;
+ switch (kinds[i]) {
+ .enumeration, .decl, .def, .constexpr => if (names[i] == name) {
+ try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ break;
+ },
+ else => {},
+ }
+ }
+ if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
+ try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters");
+ }
+ try s.syms.append(p.pp.comp.gpa, .{
+ .kind = .def,
+ .name = name,
+ .tok = tok,
+ .ty = ty,
+ .val = .{},
+ });
+}
+
+pub fn defineTag(
+ s: *SymbolStack,
+ p: *Parser,
+ name: StringId,
+ kind: Token.Id,
+ tok: TokenIndex,
+) !?Symbol {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ const end = s.scopeEnd();
+ var i = s.syms.len;
+ while (i > end) {
+ i -= 1;
+ switch (kinds[i]) {
+ .@"enum" => if (names[i] == name) {
+ if (kind == .keyword_enum) return s.syms.get(i);
+ try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ return null;
+ },
+ .@"struct" => if (names[i] == name) {
+ if (kind == .keyword_struct) return s.syms.get(i);
+ try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ return null;
+ },
+ .@"union" => if (names[i] == name) {
+ if (kind == .keyword_union) return s.syms.get(i);
+ try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ return null;
+ },
+ else => {},
+ }
+ }
+ return null;
+}
+
+pub fn defineEnumeration(
+ s: *SymbolStack,
+ p: *Parser,
+ name: StringId,
+ ty: Type,
+ tok: TokenIndex,
+ val: Value,
+) !void {
+ const kinds = s.syms.items(.kind);
+ const names = s.syms.items(.name);
+ const end = s.scopeEnd();
+ var i = s.syms.len;
+ while (i > end) {
+ i -= 1;
+ switch (kinds[i]) {
+ .enumeration => if (names[i] == name) {
+ try p.errStr(.redefinition, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ return;
+ },
+ .decl, .def, .constexpr => if (names[i] == name) {
+ try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
+ try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+ return;
+ },
+ else => {},
+ }
+ }
+ try s.syms.append(p.pp.comp.gpa, .{
+ .kind = .enumeration,
+ .name = name,
+ .tok = tok,
+ .ty = ty,
+ .val = val,
+ });
+}
deps/aro/target.zig
@@ -0,0 +1,810 @@
+const std = @import("std");
+const LangOpts = @import("LangOpts.zig");
+const Type = @import("Type.zig");
+const llvm = @import("zig").codegen.llvm;
+const TargetSet = @import("builtins/Properties.zig").TargetSet;
+
+/// intmax_t for this target
+pub fn intMaxType(target: std.Target) Type {
+ switch (target.cpu.arch) {
+ .aarch64,
+ .aarch64_be,
+ .sparc64,
+ => if (target.os.tag != .openbsd) return .{ .specifier = .long },
+
+ .bpfel,
+ .bpfeb,
+ .loongarch64,
+ .riscv64,
+ .powerpc64,
+ .powerpc64le,
+ .tce,
+ .tcele,
+ .ve,
+ => return .{ .specifier = .long },
+
+ .x86_64 => switch (target.os.tag) {
+ .windows, .openbsd => {},
+ else => switch (target.abi) {
+ .gnux32, .muslx32 => {},
+ else => return .{ .specifier = .long },
+ },
+ },
+
+ else => {},
+ }
+ return .{ .specifier = .long_long };
+}
+
+/// intptr_t for this target
+pub fn intPtrType(target: std.Target) Type {
+ switch (target.os.tag) {
+ .haiku => return .{ .specifier = .long },
+ .nacl => return .{ .specifier = .int },
+ else => {},
+ }
+
+ switch (target.cpu.arch) {
+ .aarch64, .aarch64_be => switch (target.os.tag) {
+ .windows => return .{ .specifier = .long_long },
+ else => {},
+ },
+
+ .msp430,
+ .csky,
+ .loongarch32,
+ .riscv32,
+ .xcore,
+ .hexagon,
+ .tce,
+ .tcele,
+ .m68k,
+ .spir,
+ .spirv32,
+ .arc,
+ .avr,
+ => return .{ .specifier = .int },
+
+ .sparc, .sparcel => switch (target.os.tag) {
+ .netbsd, .openbsd => {},
+ else => return .{ .specifier = .int },
+ },
+
+ .powerpc, .powerpcle => switch (target.os.tag) {
+ .linux, .freebsd, .netbsd => return .{ .specifier = .int },
+ else => {},
+ },
+
+ // 32-bit x86 Darwin, OpenBSD, and RTEMS use long (the default); others use int
+ .x86 => switch (target.os.tag) {
+ .openbsd, .rtems => {},
+ else => if (!target.os.tag.isDarwin()) return .{ .specifier = .int },
+ },
+
+ .x86_64 => switch (target.os.tag) {
+ .windows => return .{ .specifier = .long_long },
+ else => switch (target.abi) {
+ .gnux32, .muslx32 => return .{ .specifier = .int },
+ else => {},
+ },
+ },
+
+ else => {},
+ }
+
+ return .{ .specifier = .long };
+}
+
+/// int16_t for this target
+pub fn int16Type(target: std.Target) Type {
+ return switch (target.cpu.arch) {
+ .avr => .{ .specifier = .int },
+ else => .{ .specifier = .short },
+ };
+}
+
+/// int64_t for this target
+pub fn int64Type(target: std.Target) Type {
+ switch (target.cpu.arch) {
+ .loongarch64,
+ .ve,
+ .riscv64,
+ .powerpc64,
+ .powerpc64le,
+ .bpfel,
+ .bpfeb,
+ => return .{ .specifier = .long },
+
+ .sparc64 => return intMaxType(target),
+
+ .x86, .x86_64 => if (!target.isDarwin()) return intMaxType(target),
+ .aarch64, .aarch64_be => if (!target.isDarwin() and target.os.tag != .openbsd and target.os.tag != .windows) return .{ .specifier = .long },
+ else => {},
+ }
+ return .{ .specifier = .long_long };
+}
+
+/// This function returns 1 if function alignment is not observable or settable.
+pub fn defaultFunctionAlignment(target: std.Target) u8 {
+ return switch (target.cpu.arch) {
+ .arm, .armeb => 4,
+ .aarch64, .aarch64_32, .aarch64_be => 4,
+ .sparc, .sparcel, .sparc64 => 4,
+ .riscv64 => 2,
+ else => 1,
+ };
+}
+
+pub fn isTlsSupported(target: std.Target) bool {
+ if (target.isDarwin()) {
+ var supported = false;
+ switch (target.os.tag) {
+ .macos => supported = !(target.os.isAtLeast(.macos, .{ .major = 10, .minor = 7, .patch = 0 }) orelse false),
+ else => {},
+ }
+ return supported;
+ }
+ return switch (target.cpu.arch) {
+ .tce, .tcele, .bpfel, .bpfeb, .msp430, .nvptx, .nvptx64, .x86, .arm, .armeb, .thumb, .thumbeb => false,
+ else => true,
+ };
+}
+
+pub fn ignoreNonZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
+ switch (target.cpu.arch) {
+ .avr => return true,
+ .arm => {
+ if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
+ switch (target.os.tag) {
+ .ios => return true,
+ else => return false,
+ }
+ }
+ },
+ else => return false,
+ }
+ return false;
+}
+
+pub fn ignoreZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
+ switch (target.cpu.arch) {
+ .avr => return true,
+ else => return false,
+ }
+}
+
+pub fn minZeroWidthBitfieldAlignment(target: std.Target) ?u29 {
+ switch (target.cpu.arch) {
+ .avr => return 8,
+ .arm => {
+ if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
+ switch (target.os.tag) {
+ .ios => return 32,
+ else => return null,
+ }
+ } else return null;
+ },
+ else => return null,
+ }
+}
+
+pub fn unnamedFieldAffectsAlignment(target: std.Target) bool {
+ switch (target.cpu.arch) {
+ .aarch64 => {
+ if (target.isDarwin() or target.os.tag == .windows) return false;
+ return true;
+ },
+ .armeb => {
+ if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
+ if (std.Target.Abi.default(target.cpu.arch, target.os) == .eabi) return true;
+ }
+ },
+ .arm => return true,
+ .avr => return true,
+ .thumb => {
+ if (target.os.tag == .windows) return false;
+ return true;
+ },
+ else => return false,
+ }
+ return false;
+}
+
+pub fn packAllEnums(target: std.Target) bool {
+ return switch (target.cpu.arch) {
+ .hexagon => true,
+ else => false,
+ };
+}
+
+/// Default alignment (in bytes) for __attribute__((aligned)) when no alignment is specified
+pub fn defaultAlignment(target: std.Target) u29 {
+ switch (target.cpu.arch) {
+ .avr => return 1,
+ .arm => if (target.isAndroid() or target.os.tag == .ios) return 16 else return 8,
+ .sparc => if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) return 16 else return 8,
+ .mips, .mipsel => switch (target.abi) {
+ .none, .gnuabi64 => return 16,
+ else => return 8,
+ },
+ .s390x, .armeb, .thumbeb, .thumb => return 8,
+ else => return 16,
+ }
+}
+pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
+ // Android is linux but not gcc, so these checks go first
+ // the rest for documentation as fn returns .clang
+ if (target.isDarwin() or
+ target.isAndroid() or
+ target.isBSD() or
+ target.os.tag == .fuchsia or
+ target.os.tag == .solaris or
+ target.os.tag == .haiku or
+ target.cpu.arch == .hexagon)
+ {
+ return .clang;
+ }
+ if (target.os.tag == .uefi) return .msvc;
+ // this is before windows to grab WindowsGnu
+ if (target.abi.isGnu() or
+ target.os.tag == .linux)
+ {
+ return .gcc;
+ }
+ if (target.os.tag == .windows) {
+ return .msvc;
+ }
+ if (target.cpu.arch == .avr) return .gcc;
+ return .clang;
+}
+
+pub fn hasInt128(target: std.Target) bool {
+ if (target.cpu.arch == .wasm32) return true;
+ if (target.cpu.arch == .x86_64) return true;
+ return target.ptrBitWidth() >= 64;
+}
+
+pub fn hasHalfPrecisionFloatABI(target: std.Target) bool {
+ return switch (target.cpu.arch) {
+ .thumb, .thumbeb, .arm, .aarch64 => true,
+ else => false,
+ };
+}
+
+pub const FPSemantics = enum {
+ None,
+ IEEEHalf,
+ BFloat,
+ IEEESingle,
+ IEEEDouble,
+ IEEEQuad,
+ /// Minifloat 5-bit exponent 2-bit mantissa
+ E5M2,
+ /// Minifloat 4-bit exponent 3-bit mantissa
+ E4M3,
+ x87ExtendedDouble,
+ IBMExtendedDouble,
+
+ /// Only intended for generating float.h macros for the preprocessor
+ pub fn forType(ty: std.Target.CType, target: std.Target) FPSemantics {
+ std.debug.assert(ty == .float or ty == .double or ty == .longdouble);
+ return switch (target.c_type_bit_size(ty)) {
+ 32 => .IEEESingle,
+ 64 => .IEEEDouble,
+ 80 => .x87ExtendedDouble,
+ 128 => switch (target.cpu.arch) {
+ .powerpc, .powerpcle, .powerpc64, .powerpc64le => .IBMExtendedDouble,
+ else => .IEEEQuad,
+ },
+ else => unreachable,
+ };
+ }
+
+ pub fn halfPrecisionType(target: std.Target) ?FPSemantics {
+ switch (target.cpu.arch) {
+ .aarch64,
+ .aarch64_32,
+ .aarch64_be,
+ .arm,
+ .armeb,
+ .hexagon,
+ .riscv32,
+ .riscv64,
+ .spirv32,
+ .spirv64,
+ => return .IEEEHalf,
+ .x86, .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .sse2)) return .IEEEHalf,
+ else => {},
+ }
+ return null;
+ }
+
+ pub fn chooseValue(self: FPSemantics, comptime T: type, values: [6]T) T {
+ return switch (self) {
+ .IEEEHalf => values[0],
+ .IEEESingle => values[1],
+ .IEEEDouble => values[2],
+ .x87ExtendedDouble => values[3],
+ .IBMExtendedDouble => values[4],
+ .IEEEQuad => values[5],
+ else => unreachable,
+ };
+ }
+};
+
+pub fn isLP64(target: std.Target) bool {
+ return target.c_type_bit_size(.int) == 32 and target.ptrBitWidth() == 64;
+}
+
+pub fn isKnownWindowsMSVCEnvironment(target: std.Target) bool {
+ return target.os.tag == .windows and target.abi == .msvc;
+}
+
+pub fn isWindowsMSVCEnvironment(target: std.Target) bool {
+ return target.os.tag == .windows and (target.abi == .msvc or target.abi == .none);
+}
+
+pub fn isCygwinMinGW(target: std.Target) bool {
+ return target.os.tag == .windows and (target.abi == .gnu or target.abi == .cygnus);
+}
+
+pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool {
+ var copy = enabled_for;
+ var it = copy.iterator();
+ while (it.next()) |val| {
+ switch (val) {
+ .basic => return true,
+ .x86_64 => if (target.cpu.arch == .x86_64) return true,
+ .aarch64 => if (target.cpu.arch == .aarch64) return true,
+ .arm => if (target.cpu.arch == .arm) return true,
+ .ppc => switch (target.cpu.arch) {
+ .powerpc, .powerpc64, .powerpc64le => return true,
+ else => {},
+ },
+ else => {
+ // Todo: handle other target predicates
+ },
+ }
+ }
+ return false;
+}
+
+pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {
+ if (target.os.tag == .aix) return .double;
+ switch (target.cpu.arch) {
+ .x86, .x86_64 => {
+ if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) {
+ if (target.os.version_range.semver.min.order(.{ .major = 6, .minor = 99, .patch = 26 }) != .gt) {
+ // NETBSD <= 6.99.26 on 32-bit x86 defaults to double
+ return .double;
+ }
+ }
+ if (std.Target.x86.featureSetHas(target.cpu.features, .sse)) {
+ return .source;
+ }
+ return .extended;
+ },
+ else => {},
+ }
+ return .source;
+}
+
+/// Value of the `-m` flag for `ld` for this target
+pub fn ldEmulationOption(target: std.Target, arm_endianness: ?std.builtin.Endian) ?[]const u8 {
+ return switch (target.cpu.arch) {
+ .x86 => if (target.os.tag == .elfiamcu) "elf_iamcu" else "elf_i386",
+ .arm,
+ .armeb,
+ .thumb,
+ .thumbeb,
+ => switch (arm_endianness orelse target.cpu.arch.endian()) {
+ .Little => "armelf_linux_eabi",
+ .Big => "armelfb_linux_eabi",
+ },
+ .aarch64 => "aarch64linux",
+ .aarch64_be => "aarch64linuxb",
+ .m68k => "m68kelf",
+ .powerpc => if (target.os.tag == .linux) "elf32ppclinux" else "elf32ppc",
+ .powerpcle => if (target.os.tag == .linux) "elf32lppclinux" else "elf32lppc",
+ .powerpc64 => "elf64ppc",
+ .powerpc64le => "elf64lppc",
+ .riscv32 => "elf32lriscv",
+ .riscv64 => "elf64lriscv",
+ .sparc, .sparcel => "elf32_sparc",
+ .sparc64 => "elf64_sparc",
+ .loongarch32 => "elf32loongarch",
+ .loongarch64 => "elf64loongarch",
+ .mips => "elf32btsmip",
+ .mipsel => "elf32ltsmip",
+ .mips64 => if (target.abi == .gnuabin32) "elf32btsmipn32" else "elf64btsmip",
+ .mips64el => if (target.abi == .gnuabin32) "elf32ltsmipn32" else "elf64ltsmip",
+ .x86_64 => if (target.abi == .gnux32 or target.abi == .muslx32) "elf32_x86_64" else "elf_x86_64",
+ .ve => "elf64ve",
+ .csky => "cskyelf_linux",
+ else => null,
+ };
+}
+
+pub fn get32BitArchVariant(target: std.Target) ?std.Target {
+ var copy = target;
+ switch (target.cpu.arch) {
+ .amdgcn,
+ .avr,
+ .msp430,
+ .spu_2,
+ .ve,
+ .bpfel,
+ .bpfeb,
+ .s390x,
+ => return null,
+
+ .arc,
+ .arm,
+ .armeb,
+ .csky,
+ .hexagon,
+ .m68k,
+ .le32,
+ .mips,
+ .mipsel,
+ .powerpc,
+ .powerpcle,
+ .r600,
+ .riscv32,
+ .sparc,
+ .sparcel,
+ .tce,
+ .tcele,
+ .thumb,
+ .thumbeb,
+ .x86,
+ .xcore,
+ .nvptx,
+ .amdil,
+ .hsail,
+ .spir,
+ .kalimba,
+ .shave,
+ .lanai,
+ .wasm32,
+ .renderscript32,
+ .aarch64_32,
+ .spirv32,
+ .loongarch32,
+ .dxil,
+ .xtensa,
+ => {}, // Already 32 bit
+
+ .aarch64 => copy.cpu.arch = .arm,
+ .aarch64_be => copy.cpu.arch = .armeb,
+ .le64 => copy.cpu.arch = .le32,
+ .amdil64 => copy.cpu.arch = .amdil,
+ .nvptx64 => copy.cpu.arch = .nvptx,
+ .wasm64 => copy.cpu.arch = .wasm32,
+ .hsail64 => copy.cpu.arch = .hsail,
+ .spir64 => copy.cpu.arch = .spir,
+ .spirv64 => copy.cpu.arch = .spirv32,
+ .renderscript64 => copy.cpu.arch = .renderscript32,
+ .loongarch64 => copy.cpu.arch = .loongarch32,
+ .mips64 => copy.cpu.arch = .mips,
+ .mips64el => copy.cpu.arch = .mipsel,
+ .powerpc64 => copy.cpu.arch = .powerpc,
+ .powerpc64le => copy.cpu.arch = .powerpcle,
+ .riscv64 => copy.cpu.arch = .riscv32,
+ .sparc64 => copy.cpu.arch = .sparc,
+ .x86_64 => copy.cpu.arch = .x86,
+ }
+ return copy;
+}
+
+pub fn get64BitArchVariant(target: std.Target) ?std.Target {
+ var copy = target;
+ switch (target.cpu.arch) {
+ .arc,
+ .avr,
+ .csky,
+ .dxil,
+ .hexagon,
+ .kalimba,
+ .lanai,
+ .m68k,
+ .msp430,
+ .r600,
+ .shave,
+ .sparcel,
+ .spu_2,
+ .tce,
+ .tcele,
+ .xcore,
+ .xtensa,
+ => return null,
+
+ .aarch64,
+ .aarch64_be,
+ .amdgcn,
+ .bpfeb,
+ .bpfel,
+ .le64,
+ .amdil64,
+ .nvptx64,
+ .wasm64,
+ .hsail64,
+ .spir64,
+ .spirv64,
+ .renderscript64,
+ .loongarch64,
+ .mips64,
+ .mips64el,
+ .powerpc64,
+ .powerpc64le,
+ .riscv64,
+ .s390x,
+ .sparc64,
+ .ve,
+ .x86_64,
+ => {}, // Already 64 bit
+
+ .aarch64_32 => copy.cpu.arch = .aarch64,
+ .amdil => copy.cpu.arch = .amdil64,
+ .arm => copy.cpu.arch = .aarch64,
+ .armeb => copy.cpu.arch = .aarch64_be,
+ .hsail => copy.cpu.arch = .hsail64,
+ .le32 => copy.cpu.arch = .le64,
+ .loongarch32 => copy.cpu.arch = .loongarch64,
+ .mips => copy.cpu.arch = .mips64,
+ .mipsel => copy.cpu.arch = .mips64el,
+ .nvptx => copy.cpu.arch = .nvptx64,
+ .powerpc => copy.cpu.arch = .powerpc64,
+ .powerpcle => copy.cpu.arch = .powerpc64le,
+ .renderscript32 => copy.cpu.arch = .renderscript64,
+ .riscv32 => copy.cpu.arch = .riscv64,
+ .sparc => copy.cpu.arch = .sparc64,
+ .spir => copy.cpu.arch = .spir64,
+ .spirv32 => copy.cpu.arch = .spirv64,
+ .thumb => copy.cpu.arch = .aarch64,
+ .thumbeb => copy.cpu.arch = .aarch64_be,
+ .wasm32 => copy.cpu.arch = .wasm64,
+ .x86 => copy.cpu.arch = .x86_64,
+ }
+ return copy;
+}
+
+/// Adapted from Zig's src/codegen/llvm.zig
+pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
+ // 64 bytes is assumed to be large enough to hold any target triple; increase if necessary
+ std.debug.assert(buf.len >= 64);
+
+ var stream = std.io.fixedBufferStream(buf);
+ const writer = stream.writer();
+
+ const llvm_arch = switch (target.cpu.arch) {
+ .arm => "arm",
+ .armeb => "armeb",
+ .aarch64 => "aarch64",
+ .aarch64_be => "aarch64_be",
+ .aarch64_32 => "aarch64_32",
+ .arc => "arc",
+ .avr => "avr",
+ .bpfel => "bpfel",
+ .bpfeb => "bpfeb",
+ .csky => "csky",
+ .dxil => "dxil",
+ .hexagon => "hexagon",
+ .loongarch32 => "loongarch32",
+ .loongarch64 => "loongarch64",
+ .m68k => "m68k",
+ .mips => "mips",
+ .mipsel => "mipsel",
+ .mips64 => "mips64",
+ .mips64el => "mips64el",
+ .msp430 => "msp430",
+ .powerpc => "powerpc",
+ .powerpcle => "powerpcle",
+ .powerpc64 => "powerpc64",
+ .powerpc64le => "powerpc64le",
+ .r600 => "r600",
+ .amdgcn => "amdgcn",
+ .riscv32 => "riscv32",
+ .riscv64 => "riscv64",
+ .sparc => "sparc",
+ .sparc64 => "sparc64",
+ .sparcel => "sparcel",
+ .s390x => "s390x",
+ .tce => "tce",
+ .tcele => "tcele",
+ .thumb => "thumb",
+ .thumbeb => "thumbeb",
+ .x86 => "i386",
+ .x86_64 => "x86_64",
+ .xcore => "xcore",
+ .xtensa => "xtensa",
+ .nvptx => "nvptx",
+ .nvptx64 => "nvptx64",
+ .le32 => "le32",
+ .le64 => "le64",
+ .amdil => "amdil",
+ .amdil64 => "amdil64",
+ .hsail => "hsail",
+ .hsail64 => "hsail64",
+ .spir => "spir",
+ .spir64 => "spir64",
+ .spirv32 => "spirv32",
+ .spirv64 => "spirv64",
+ .kalimba => "kalimba",
+ .shave => "shave",
+ .lanai => "lanai",
+ .wasm32 => "wasm32",
+ .wasm64 => "wasm64",
+ .renderscript32 => "renderscript32",
+ .renderscript64 => "renderscript64",
+ .ve => "ve",
+ // Note: spu_2 is not supported in LLVM; this is the Zig arch name
+ .spu_2 => "spu_2",
+ };
+ writer.writeAll(llvm_arch) catch unreachable;
+ writer.writeByte('-') catch unreachable;
+
+ const llvm_os = switch (target.os.tag) {
+ .freestanding => "unknown",
+ .ananas => "ananas",
+ .cloudabi => "cloudabi",
+ .dragonfly => "dragonfly",
+ .freebsd => "freebsd",
+ .fuchsia => "fuchsia",
+ .kfreebsd => "kfreebsd",
+ .linux => "linux",
+ .lv2 => "lv2",
+ .netbsd => "netbsd",
+ .openbsd => "openbsd",
+ .solaris => "solaris",
+ .windows => "windows",
+ .zos => "zos",
+ .haiku => "haiku",
+ .minix => "minix",
+ .rtems => "rtems",
+ .nacl => "nacl",
+ .aix => "aix",
+ .cuda => "cuda",
+ .nvcl => "nvcl",
+ .amdhsa => "amdhsa",
+ .ps4 => "ps4",
+ .ps5 => "ps5",
+ .elfiamcu => "elfiamcu",
+ .mesa3d => "mesa3d",
+ .contiki => "contiki",
+ .amdpal => "amdpal",
+ .hermit => "hermit",
+ .hurd => "hurd",
+ .wasi => "wasi",
+ .emscripten => "emscripten",
+ .uefi => "windows",
+ .macos => "macosx",
+ .ios => "ios",
+ .tvos => "tvos",
+ .watchos => "watchos",
+ .driverkit => "driverkit",
+ .shadermodel => "shadermodel",
+ .opencl,
+ .glsl450,
+ .vulkan,
+ .plan9,
+ .other,
+ => "unknown",
+ };
+ writer.writeAll(llvm_os) catch unreachable;
+
+ if (target.os.tag.isDarwin()) {
+ const min_version = target.os.version_range.semver.min;
+ writer.print("{d}.{d}.{d}", .{
+ min_version.major,
+ min_version.minor,
+ min_version.patch,
+ }) catch unreachable;
+ }
+ writer.writeByte('-') catch unreachable;
+
+ const llvm_abi = switch (target.abi) {
+ .none => "unknown",
+ .gnu => "gnu",
+ .gnuabin32 => "gnuabin32",
+ .gnuabi64 => "gnuabi64",
+ .gnueabi => "gnueabi",
+ .gnueabihf => "gnueabihf",
+ .gnuf32 => "gnuf32",
+ .gnuf64 => "gnuf64",
+ .gnusf => "gnusf",
+ .gnux32 => "gnux32",
+ .gnuilp32 => "gnuilp32",
+ .code16 => "code16",
+ .eabi => "eabi",
+ .eabihf => "eabihf",
+ .android => "android",
+ .musl => "musl",
+ .musleabi => "musleabi",
+ .musleabihf => "musleabihf",
+ .muslx32 => "muslx32",
+ .msvc => "msvc",
+ .itanium => "itanium",
+ .cygnus => "cygnus",
+ .coreclr => "coreclr",
+ .simulator => "simulator",
+ .macabi => "macabi",
+ .pixel => "pixel",
+ .vertex => "vertex",
+ .geometry => "geometry",
+ .hull => "hull",
+ .domain => "domain",
+ .compute => "compute",
+ .library => "library",
+ .raygeneration => "raygeneration",
+ .intersection => "intersection",
+ .anyhit => "anyhit",
+ .closesthit => "closesthit",
+ .miss => "miss",
+ .callable => "callable",
+ .mesh => "mesh",
+ .amplification => "amplification",
+ };
+ writer.writeAll(llvm_abi) catch unreachable;
+ return stream.getWritten();
+}
+
+test "alignment functions - smoke test" {
+ var target: std.Target = undefined;
+ const x86 = std.Target.Cpu.Arch.x86_64;
+ target.cpu = std.Target.Cpu.baseline(x86);
+ target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
+ target.abi = std.Target.Abi.default(x86, target.os);
+
+ try std.testing.expect(isTlsSupported(target));
+ try std.testing.expect(!ignoreNonZeroSizedBitfieldTypeAlignment(target));
+ try std.testing.expect(minZeroWidthBitfieldAlignment(target) == null);
+ try std.testing.expect(!unnamedFieldAffectsAlignment(target));
+ try std.testing.expect(defaultAlignment(target) == 16);
+ try std.testing.expect(!packAllEnums(target));
+ try std.testing.expect(systemCompiler(target) == .gcc);
+
+ const arm = std.Target.Cpu.Arch.arm;
+ target.cpu = std.Target.Cpu.baseline(arm);
+ target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
+ target.abi = std.Target.Abi.default(arm, target.os);
+
+ try std.testing.expect(!isTlsSupported(target));
+ try std.testing.expect(ignoreNonZeroSizedBitfieldTypeAlignment(target));
+ try std.testing.expectEqual(@as(?u29, 32), minZeroWidthBitfieldAlignment(target));
+ try std.testing.expect(unnamedFieldAffectsAlignment(target));
+ try std.testing.expect(defaultAlignment(target) == 16);
+ try std.testing.expect(!packAllEnums(target));
+ try std.testing.expect(systemCompiler(target) == .clang);
+}
+
+test "target size/align tests" {
+ var comp: @import("Compilation.zig") = undefined;
+
+ const x86 = std.Target.Cpu.Arch.x86;
+ comp.target.cpu.arch = x86;
+ comp.target.cpu.model = &std.Target.x86.cpu.i586;
+ comp.target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
+ comp.target.abi = std.Target.Abi.gnu;
+
+ const tt: Type = .{
+ .specifier = .long_long,
+ };
+
+ try std.testing.expectEqual(@as(u64, 8), tt.sizeof(&comp).?);
+ try std.testing.expectEqual(@as(u64, 4), tt.alignof(&comp));
+
+ const arm = std.Target.Cpu.Arch.arm;
+ comp.target.cpu = std.Target.Cpu.Model.toCpu(&std.Target.arm.cpu.cortex_r4, arm);
+ comp.target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
+ comp.target.abi = std.Target.Abi.none;
+
+ const ct: Type = .{
+ .specifier = .char,
+ };
+
+ try std.testing.expectEqual(true, std.Target.arm.featureSetHas(comp.target.cpu.features, .has_v7));
+ try std.testing.expectEqual(@as(u64, 1), ct.sizeof(&comp).?);
+ try std.testing.expectEqual(@as(u64, 1), ct.alignof(&comp));
+ try std.testing.expectEqual(true, ignoreNonZeroSizedBitfieldTypeAlignment(comp.target));
+}
deps/aro/Tokenizer.zig
@@ -0,0 +1,2140 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const Compilation = @import("Compilation.zig");
+const Source = @import("Source.zig");
+const LangOpts = @import("LangOpts.zig");
+const CharInfo = @import("CharInfo.zig");
+const unicode = @import("unicode.zig");
+
+const Tokenizer = @This();
+
+pub const Token = struct {
+ id: Id,
+ source: Source.Id,
+ start: u32 = 0,
+ end: u32 = 0,
+ line: u32 = 0,
+
+ pub const Id = enum(u8) {
+ invalid,
+ nl,
+ whitespace,
+ eof,
+ /// identifier containing solely basic character set characters
+ identifier,
+ /// identifier with at least one extended character
+ extended_identifier,
+
+ // string literals with prefixes
+ string_literal,
+ string_literal_utf_16,
+ string_literal_utf_8,
+ string_literal_utf_32,
+ string_literal_wide,
+
+ // <foobar> only generated by preprocessor
+ macro_string,
+
+ // char literals with prefixes
+ char_literal,
+ char_literal_utf_8,
+ char_literal_utf_16,
+ char_literal_utf_32,
+ char_literal_wide,
+
+ /// Integer literal tokens generated by preprocessor.
+ one,
+ zero,
+
+ bang,
+ bang_equal,
+ pipe,
+ pipe_pipe,
+ pipe_equal,
+ equal,
+ equal_equal,
+ l_paren,
+ r_paren,
+ l_brace,
+ r_brace,
+ l_bracket,
+ r_bracket,
+ period,
+ ellipsis,
+ caret,
+ caret_equal,
+ plus,
+ plus_plus,
+ plus_equal,
+ minus,
+ minus_minus,
+ minus_equal,
+ asterisk,
+ asterisk_equal,
+ percent,
+ percent_equal,
+ arrow,
+ colon,
+ colon_colon,
+ semicolon,
+ slash,
+ slash_equal,
+ comma,
+ ampersand,
+ ampersand_ampersand,
+ ampersand_equal,
+ question_mark,
+ angle_bracket_left,
+ angle_bracket_left_equal,
+ angle_bracket_angle_bracket_left,
+ angle_bracket_angle_bracket_left_equal,
+ angle_bracket_right,
+ angle_bracket_right_equal,
+ angle_bracket_angle_bracket_right,
+ angle_bracket_angle_bracket_right_equal,
+ tilde,
+ hash,
+ hash_hash,
+
+ /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
+ macro_param,
+ /// Special token to signal that the argument must be replaced without expansion (e.g. in concatenation)
+ macro_param_no_expand,
+ /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
+ stringify_param,
+ /// Same as stringify_param, but for var args
+ stringify_va_args,
+ /// Special macro whitespace, always equal to a single space
+ macro_ws,
+ /// Special token for implementing __has_attribute
+ macro_param_has_attribute,
+ /// Special token for implementing __has_warning
+ macro_param_has_warning,
+ /// Special token for implementing __has_feature
+ macro_param_has_feature,
+ /// Special token for implementing __has_extension
+ macro_param_has_extension,
+ /// Special token for implementing __has_builtin
+ macro_param_has_builtin,
+ /// Special token for implementing __has_include
+ macro_param_has_include,
+ /// Special token for implementing __has_include_next
+ macro_param_has_include_next,
+ /// Special token for implementing __is_identifier
+ macro_param_is_identifier,
+ /// Special token for implementing __FILE__
+ macro_file,
+ /// Special token for implementing __LINE__
+ macro_line,
+ /// Special token for implementing __COUNTER__
+ macro_counter,
+ /// Special token for implementing _Pragma
+ macro_param_pragma_operator,
+
+ /// Special identifier for implementing __func__
+ macro_func,
+ /// Special identifier for implementing __FUNCTION__
+ macro_function,
+ /// Special identifier for implementing __PRETTY_FUNCTION__
+ macro_pretty_func,
+
+ keyword_auto,
+ keyword_auto_type,
+ keyword_break,
+ keyword_case,
+ keyword_char,
+ keyword_const,
+ keyword_continue,
+ keyword_default,
+ keyword_do,
+ keyword_double,
+ keyword_else,
+ keyword_enum,
+ keyword_extern,
+ keyword_float,
+ keyword_for,
+ keyword_goto,
+ keyword_if,
+ keyword_int,
+ keyword_long,
+ keyword_register,
+ keyword_return,
+ keyword_short,
+ keyword_signed,
+ keyword_sizeof,
+ keyword_static,
+ keyword_struct,
+ keyword_switch,
+ keyword_typedef,
+ keyword_typeof1,
+ keyword_typeof2,
+ keyword_union,
+ keyword_unsigned,
+ keyword_void,
+ keyword_volatile,
+ keyword_while,
+
+ // ISO C99
+ keyword_bool,
+ keyword_complex,
+ keyword_imaginary,
+ keyword_inline,
+ keyword_restrict,
+
+ // ISO C11
+ keyword_alignas,
+ keyword_alignof,
+ keyword_atomic,
+ keyword_generic,
+ keyword_noreturn,
+ keyword_static_assert,
+ keyword_thread_local,
+
+ // ISO C23
+ keyword_bit_int,
+ keyword_c23_alignas,
+ keyword_c23_alignof,
+ keyword_c23_bool,
+ keyword_c23_static_assert,
+ keyword_c23_thread_local,
+ keyword_constexpr,
+ keyword_true,
+ keyword_false,
+ keyword_nullptr,
+
+ // Preprocessor directives
+ keyword_include,
+ keyword_include_next,
+ keyword_embed,
+ keyword_define,
+ keyword_defined,
+ keyword_undef,
+ keyword_ifdef,
+ keyword_ifndef,
+ keyword_elif,
+ keyword_elifdef,
+ keyword_elifndef,
+ keyword_endif,
+ keyword_error,
+ keyword_warning,
+ keyword_pragma,
+ keyword_line,
+ keyword_va_args,
+
+ // gcc keywords
+ keyword_const1,
+ keyword_const2,
+ keyword_inline1,
+ keyword_inline2,
+ keyword_volatile1,
+ keyword_volatile2,
+ keyword_restrict1,
+ keyword_restrict2,
+ keyword_alignof1,
+ keyword_alignof2,
+ keyword_typeof,
+ keyword_attribute1,
+ keyword_attribute2,
+ keyword_extension,
+ keyword_asm,
+ keyword_asm1,
+ keyword_asm2,
+ keyword_float80,
+ keyword_float128,
+ keyword_int128,
+ keyword_imag1,
+ keyword_imag2,
+ keyword_real1,
+ keyword_real2,
+ keyword_float16,
+
+ // clang keywords
+ keyword_fp16,
+
+ // ms keywords
+ keyword_declspec,
+ keyword_int64,
+ keyword_int64_2,
+ keyword_int32,
+ keyword_int32_2,
+ keyword_int16,
+ keyword_int16_2,
+ keyword_int8,
+ keyword_int8_2,
+ keyword_stdcall,
+ keyword_stdcall2,
+ keyword_thiscall,
+ keyword_thiscall2,
+ keyword_vectorcall,
+ keyword_vectorcall2,
+
+ // builtins that require special parsing
+ builtin_choose_expr,
+ builtin_va_arg,
+ builtin_offsetof,
+ builtin_bitoffsetof,
+ builtin_types_compatible_p,
+
+ /// Generated by #embed directive
+ /// Decimal value with no prefix or suffix
+ embed_byte,
+
+ /// preprocessor number
+ /// An optional period, followed by a digit 0-9, followed by any number of letters
+ /// digits, underscores, periods, and exponents (e+, e-, E+, E-, p+, p-, P+, P-)
+ pp_num,
+
+ /// preprocessor placemarker token
+ /// generated if `##` is used with a zero-token argument
+ /// removed after substitution, so the parser should never see this
+ /// See C99 6.10.3.3.2
+ placemarker,
+
+ /// Return true if token is identifier or keyword.
+ pub fn isMacroIdentifier(id: Id) bool {
+ switch (id) {
+ .keyword_include,
+ .keyword_include_next,
+ .keyword_embed,
+ .keyword_define,
+ .keyword_defined,
+ .keyword_undef,
+ .keyword_ifdef,
+ .keyword_ifndef,
+ .keyword_elif,
+ .keyword_elifdef,
+ .keyword_elifndef,
+ .keyword_endif,
+ .keyword_error,
+ .keyword_warning,
+ .keyword_pragma,
+ .keyword_line,
+ .keyword_va_args,
+ .macro_func,
+ .macro_function,
+ .macro_pretty_func,
+ .keyword_auto,
+ .keyword_auto_type,
+ .keyword_break,
+ .keyword_case,
+ .keyword_char,
+ .keyword_const,
+ .keyword_continue,
+ .keyword_default,
+ .keyword_do,
+ .keyword_double,
+ .keyword_else,
+ .keyword_enum,
+ .keyword_extern,
+ .keyword_float,
+ .keyword_for,
+ .keyword_goto,
+ .keyword_if,
+ .keyword_int,
+ .keyword_long,
+ .keyword_register,
+ .keyword_return,
+ .keyword_short,
+ .keyword_signed,
+ .keyword_sizeof,
+ .keyword_static,
+ .keyword_struct,
+ .keyword_switch,
+ .keyword_typedef,
+ .keyword_union,
+ .keyword_unsigned,
+ .keyword_void,
+ .keyword_volatile,
+ .keyword_while,
+ .keyword_bool,
+ .keyword_complex,
+ .keyword_imaginary,
+ .keyword_inline,
+ .keyword_restrict,
+ .keyword_alignas,
+ .keyword_alignof,
+ .keyword_atomic,
+ .keyword_generic,
+ .keyword_noreturn,
+ .keyword_static_assert,
+ .keyword_thread_local,
+ .identifier,
+ .extended_identifier,
+ .keyword_typeof,
+ .keyword_typeof1,
+ .keyword_typeof2,
+ .keyword_const1,
+ .keyword_const2,
+ .keyword_inline1,
+ .keyword_inline2,
+ .keyword_volatile1,
+ .keyword_volatile2,
+ .keyword_restrict1,
+ .keyword_restrict2,
+ .keyword_alignof1,
+ .keyword_alignof2,
+ .builtin_choose_expr,
+ .builtin_va_arg,
+ .builtin_offsetof,
+ .builtin_bitoffsetof,
+ .builtin_types_compatible_p,
+ .keyword_attribute1,
+ .keyword_attribute2,
+ .keyword_extension,
+ .keyword_asm,
+ .keyword_asm1,
+ .keyword_asm2,
+ .keyword_float80,
+ .keyword_float128,
+ .keyword_int128,
+ .keyword_imag1,
+ .keyword_imag2,
+ .keyword_real1,
+ .keyword_real2,
+ .keyword_float16,
+ .keyword_fp16,
+ .keyword_declspec,
+ .keyword_int64,
+ .keyword_int64_2,
+ .keyword_int32,
+ .keyword_int32_2,
+ .keyword_int16,
+ .keyword_int16_2,
+ .keyword_int8,
+ .keyword_int8_2,
+ .keyword_stdcall,
+ .keyword_stdcall2,
+ .keyword_thiscall,
+ .keyword_thiscall2,
+ .keyword_vectorcall,
+ .keyword_vectorcall2,
+ .keyword_bit_int,
+ .keyword_c23_alignas,
+ .keyword_c23_alignof,
+ .keyword_c23_bool,
+ .keyword_c23_static_assert,
+ .keyword_c23_thread_local,
+ .keyword_constexpr,
+ .keyword_true,
+ .keyword_false,
+ .keyword_nullptr,
+ => return true,
+ else => return false,
+ }
+ }
+
+ /// Turn macro keywords into identifiers.
+ /// `keyword_defined` is special since it should only turn into an identifier if
+ /// we are *not* in an #if or #elif expression
+ pub fn simplifyMacroKeywordExtra(id: *Id, defined_to_identifier: bool) void {
+ switch (id.*) {
+ .keyword_include,
+ .keyword_include_next,
+ .keyword_embed,
+ .keyword_define,
+ .keyword_undef,
+ .keyword_ifdef,
+ .keyword_ifndef,
+ .keyword_elif,
+ .keyword_elifdef,
+ .keyword_elifndef,
+ .keyword_endif,
+ .keyword_error,
+ .keyword_warning,
+ .keyword_pragma,
+ .keyword_line,
+ .keyword_va_args,
+ => id.* = .identifier,
+ .keyword_defined => if (defined_to_identifier) {
+ id.* = .identifier;
+ },
+ else => {},
+ }
+ }
+
+ pub fn simplifyMacroKeyword(id: *Id) void {
+ simplifyMacroKeywordExtra(id, false);
+ }
+
+ pub fn lexeme(id: Id) ?[]const u8 {
+ return switch (id) {
+ .invalid,
+ .identifier,
+ .extended_identifier,
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ .char_literal,
+ .char_literal_utf_8,
+ .char_literal_utf_16,
+ .char_literal_utf_32,
+ .char_literal_wide,
+ .macro_string,
+ .whitespace,
+ .pp_num,
+ .embed_byte,
+ => null,
+
+ .zero => "0",
+ .one => "1",
+
+ .nl,
+ .eof,
+ .macro_param,
+ .macro_param_no_expand,
+ .stringify_param,
+ .stringify_va_args,
+ .macro_param_has_attribute,
+ .macro_param_has_warning,
+ .macro_param_has_feature,
+ .macro_param_has_extension,
+ .macro_param_has_builtin,
+ .macro_param_has_include,
+ .macro_param_has_include_next,
+ .macro_param_is_identifier,
+ .macro_file,
+ .macro_line,
+ .macro_counter,
+ .macro_param_pragma_operator,
+ .placemarker,
+ => "",
+ .macro_ws => " ",
+
+ .macro_func => "__func__",
+ .macro_function => "__FUNCTION__",
+ .macro_pretty_func => "__PRETTY_FUNCTION__",
+
+ .bang => "!",
+ .bang_equal => "!=",
+ .pipe => "|",
+ .pipe_pipe => "||",
+ .pipe_equal => "|=",
+ .equal => "=",
+ .equal_equal => "==",
+ .l_paren => "(",
+ .r_paren => ")",
+ .l_brace => "{",
+ .r_brace => "}",
+ .l_bracket => "[",
+ .r_bracket => "]",
+ .period => ".",
+ .ellipsis => "...",
+ .caret => "^",
+ .caret_equal => "^=",
+ .plus => "+",
+ .plus_plus => "++",
+ .plus_equal => "+=",
+ .minus => "-",
+ .minus_minus => "--",
+ .minus_equal => "-=",
+ .asterisk => "*",
+ .asterisk_equal => "*=",
+ .percent => "%",
+ .percent_equal => "%=",
+ .arrow => "->",
+ .colon => ":",
+ .colon_colon => "::",
+ .semicolon => ";",
+ .slash => "/",
+ .slash_equal => "/=",
+ .comma => ",",
+ .ampersand => "&",
+ .ampersand_ampersand => "&&",
+ .ampersand_equal => "&=",
+ .question_mark => "?",
+ .angle_bracket_left => "<",
+ .angle_bracket_left_equal => "<=",
+ .angle_bracket_angle_bracket_left => "<<",
+ .angle_bracket_angle_bracket_left_equal => "<<=",
+ .angle_bracket_right => ">",
+ .angle_bracket_right_equal => ">=",
+ .angle_bracket_angle_bracket_right => ">>",
+ .angle_bracket_angle_bracket_right_equal => ">>=",
+ .tilde => "~",
+ .hash => "#",
+ .hash_hash => "##",
+
+ .keyword_auto => "auto",
+ .keyword_auto_type => "__auto_type",
+ .keyword_break => "break",
+ .keyword_case => "case",
+ .keyword_char => "char",
+ .keyword_const => "const",
+ .keyword_continue => "continue",
+ .keyword_default => "default",
+ .keyword_do => "do",
+ .keyword_double => "double",
+ .keyword_else => "else",
+ .keyword_enum => "enum",
+ .keyword_extern => "extern",
+ .keyword_float => "float",
+ .keyword_for => "for",
+ .keyword_goto => "goto",
+ .keyword_if => "if",
+ .keyword_int => "int",
+ .keyword_long => "long",
+ .keyword_register => "register",
+ .keyword_return => "return",
+ .keyword_short => "short",
+ .keyword_signed => "signed",
+ .keyword_sizeof => "sizeof",
+ .keyword_static => "static",
+ .keyword_struct => "struct",
+ .keyword_switch => "switch",
+ .keyword_typedef => "typedef",
+ .keyword_typeof => "typeof",
+ .keyword_union => "union",
+ .keyword_unsigned => "unsigned",
+ .keyword_void => "void",
+ .keyword_volatile => "volatile",
+ .keyword_while => "while",
+ .keyword_bool => "_Bool",
+ .keyword_complex => "_Complex",
+ .keyword_imaginary => "_Imaginary",
+ .keyword_inline => "inline",
+ .keyword_restrict => "restrict",
+ .keyword_alignas => "_Alignas",
+ .keyword_alignof => "_Alignof",
+ .keyword_atomic => "_Atomic",
+ .keyword_generic => "_Generic",
+ .keyword_noreturn => "_Noreturn",
+ .keyword_static_assert => "_Static_assert",
+ .keyword_thread_local => "_Thread_local",
+ .keyword_bit_int => "_BitInt",
+ .keyword_c23_alignas => "alignas",
+ .keyword_c23_alignof => "alignof",
+ .keyword_c23_bool => "bool",
+ .keyword_c23_static_assert => "static_assert",
+ .keyword_c23_thread_local => "thread_local",
+ .keyword_constexpr => "constexpr",
+ .keyword_true => "true",
+ .keyword_false => "false",
+ .keyword_nullptr => "nullptr",
+ .keyword_include => "include",
+ .keyword_include_next => "include_next",
+ .keyword_embed => "embed",
+ .keyword_define => "define",
+ .keyword_defined => "defined",
+ .keyword_undef => "undef",
+ .keyword_ifdef => "ifdef",
+ .keyword_ifndef => "ifndef",
+ .keyword_elif => "elif",
+ .keyword_elifdef => "elifdef",
+ .keyword_elifndef => "elifndef",
+ .keyword_endif => "endif",
+ .keyword_error => "error",
+ .keyword_warning => "warning",
+ .keyword_pragma => "pragma",
+ .keyword_line => "line",
+ .keyword_va_args => "__VA_ARGS__",
+ .keyword_const1 => "__const",
+ .keyword_const2 => "__const__",
+ .keyword_inline1 => "__inline",
+ .keyword_inline2 => "__inline__",
+ .keyword_volatile1 => "__volatile",
+ .keyword_volatile2 => "__volatile__",
+ .keyword_restrict1 => "__restrict",
+ .keyword_restrict2 => "__restrict__",
+ .keyword_alignof1 => "__alignof",
+ .keyword_alignof2 => "__alignof__",
+ .keyword_typeof1 => "__typeof",
+ .keyword_typeof2 => "__typeof__",
+ .builtin_choose_expr => "__builtin_choose_expr",
+ .builtin_va_arg => "__builtin_va_arg",
+ .builtin_offsetof => "__builtin_offsetof",
+ .builtin_bitoffsetof => "__builtin_bitoffsetof",
+ .builtin_types_compatible_p => "__builtin_types_compatible_p",
+ .keyword_attribute1 => "__attribute",
+ .keyword_attribute2 => "__attribute__",
+ .keyword_extension => "__extension__",
+ .keyword_asm => "asm",
+ .keyword_asm1 => "__asm",
+ .keyword_asm2 => "__asm__",
+ .keyword_float80 => "__float80",
+ .keyword_float128 => "__float18",
+ .keyword_int128 => "__int128",
+ .keyword_imag1 => "__imag",
+ .keyword_imag2 => "__imag__",
+ .keyword_real1 => "__real",
+ .keyword_real2 => "__real__",
+ .keyword_float16 => "_Float16",
+ .keyword_fp16 => "__fp16",
+ .keyword_declspec => "__declspec",
+ .keyword_int64 => "__int64",
+ .keyword_int64_2 => "_int64",
+ .keyword_int32 => "__int32",
+ .keyword_int32_2 => "_int32",
+ .keyword_int16 => "__int16",
+ .keyword_int16_2 => "_int16",
+ .keyword_int8 => "__int8",
+ .keyword_int8_2 => "_int8",
+ .keyword_stdcall => "__stdcall",
+ .keyword_stdcall2 => "_stdcall",
+ .keyword_thiscall => "__thiscall",
+ .keyword_thiscall2 => "_thiscall",
+ .keyword_vectorcall => "__vectorcall",
+ .keyword_vectorcall2 => "_vectorcall",
+ };
+ }
+
+ pub fn symbol(id: Id) []const u8 {
+ return switch (id) {
+ .macro_string, .invalid => unreachable,
+ .identifier,
+ .extended_identifier,
+ .macro_func,
+ .macro_function,
+ .macro_pretty_func,
+ .builtin_choose_expr,
+ .builtin_va_arg,
+ .builtin_offsetof,
+ .builtin_bitoffsetof,
+ .builtin_types_compatible_p,
+ => "an identifier",
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ => "a string literal",
+ .char_literal,
+ .char_literal_utf_8,
+ .char_literal_utf_16,
+ .char_literal_utf_32,
+ .char_literal_wide,
+ => "a character literal",
+ .pp_num, .embed_byte => "A number",
+ else => id.lexeme().?,
+ };
+ }
+
+ /// tokens that can start an expression parsed by Preprocessor.expr
+ /// Note that eof, r_paren, and string literals cannot actually start a
+ /// preprocessor expression, but we include them here so that a nicer
+ /// error message can be generated by the parser.
+ pub fn validPreprocessorExprStart(id: Id) bool {
+ return switch (id) {
+ .eof,
+ .r_paren,
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+
+ .char_literal,
+ .char_literal_utf_8,
+ .char_literal_utf_16,
+ .char_literal_utf_32,
+ .char_literal_wide,
+ .l_paren,
+ .plus,
+ .minus,
+ .tilde,
+ .bang,
+ .identifier,
+ .extended_identifier,
+ .keyword_defined,
+ .one,
+ .zero,
+ .pp_num,
+ .keyword_true,
+ .keyword_false,
+ => true,
+ else => false,
+ };
+ }
+
+ pub fn allowsDigraphs(id: Id, comp: *const Compilation) bool {
+ return switch (id) {
+ .l_bracket,
+ .r_bracket,
+ .l_brace,
+ .r_brace,
+ .hash,
+ .hash_hash,
+ => comp.langopts.hasDigraphs(),
+ else => false,
+ };
+ }
+
+ pub fn canOpenGCCAsmStmt(id: Id) bool {
+ return switch (id) {
+ .keyword_volatile, .keyword_volatile1, .keyword_volatile2, .keyword_inline, .keyword_inline1, .keyword_inline2, .keyword_goto, .l_paren => true,
+ else => false,
+ };
+ }
+
+ pub fn isStringLiteral(id: Id) bool {
+ return switch (id) {
+ .string_literal, .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32, .string_literal_wide => true,
+ else => false,
+ };
+ }
+ };
+
+ /// double underscore and underscore + capital letter identifiers
+ /// belong to the implementation namespace, so we always convert them
+ /// to keywords.
+ pub fn getTokenId(comp: *const Compilation, str: []const u8) Token.Id {
+ const kw = all_kws.get(str) orelse return .identifier;
+ const standard = comp.langopts.standard;
+ return switch (kw) {
+ .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier,
+ .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier,
+ .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c2x)) kw else .identifier,
+ .keyword_asm => if (standard.isGNU()) kw else .identifier,
+ .keyword_declspec => if (comp.langopts.declspec_attrs) kw else .identifier,
+
+ .keyword_c23_alignas,
+ .keyword_c23_alignof,
+ .keyword_c23_bool,
+ .keyword_c23_static_assert,
+ .keyword_c23_thread_local,
+ .keyword_constexpr,
+ .keyword_true,
+ .keyword_false,
+ .keyword_nullptr,
+ .keyword_elifdef,
+ .keyword_elifndef,
+ => if (standard.atLeast(.c2x)) kw else .identifier,
+
+ .keyword_int64,
+ .keyword_int64_2,
+ .keyword_int32,
+ .keyword_int32_2,
+ .keyword_int16,
+ .keyword_int16_2,
+ .keyword_int8,
+ .keyword_int8_2,
+ .keyword_stdcall2,
+ .keyword_thiscall2,
+ .keyword_vectorcall2,
+ => if (comp.langopts.ms_extensions) kw else .identifier,
+ else => kw,
+ };
+ }
+
+ /// Check if codepoint may appear in specified context
+ /// does not check basic character set chars because the tokenizer handles them separately to keep the common
+ /// case on the fast path
+ pub fn mayAppearInIdent(comp: *const Compilation, codepoint: u21, where: enum { start, inside }) bool {
+ if (codepoint == '$') return comp.langopts.dollars_in_identifiers;
+ if (codepoint <= 0x7F) return false;
+ return switch (where) {
+ .start => if (comp.langopts.standard.atLeast(.c11))
+ CharInfo.isC11IdChar(codepoint) and !CharInfo.isC11DisallowedInitialIdChar(codepoint)
+ else
+ CharInfo.isC99IdChar(codepoint) and !CharInfo.isC99DisallowedInitialIDChar(codepoint),
+ .inside => if (comp.langopts.standard.atLeast(.c11))
+ CharInfo.isC11IdChar(codepoint)
+ else
+ CharInfo.isC99IdChar(codepoint),
+ };
+ }
+
+ const all_kws = std.ComptimeStringMap(Id, .{
+ .{ "auto", auto: {
+ @setEvalBranchQuota(3000);
+ break :auto .keyword_auto;
+ } },
+ .{ "break", .keyword_break },
+ .{ "case", .keyword_case },
+ .{ "char", .keyword_char },
+ .{ "const", .keyword_const },
+ .{ "continue", .keyword_continue },
+ .{ "default", .keyword_default },
+ .{ "do", .keyword_do },
+ .{ "double", .keyword_double },
+ .{ "else", .keyword_else },
+ .{ "enum", .keyword_enum },
+ .{ "extern", .keyword_extern },
+ .{ "float", .keyword_float },
+ .{ "for", .keyword_for },
+ .{ "goto", .keyword_goto },
+ .{ "if", .keyword_if },
+ .{ "int", .keyword_int },
+ .{ "long", .keyword_long },
+ .{ "register", .keyword_register },
+ .{ "return", .keyword_return },
+ .{ "short", .keyword_short },
+ .{ "signed", .keyword_signed },
+ .{ "sizeof", .keyword_sizeof },
+ .{ "static", .keyword_static },
+ .{ "struct", .keyword_struct },
+ .{ "switch", .keyword_switch },
+ .{ "typedef", .keyword_typedef },
+ .{ "union", .keyword_union },
+ .{ "unsigned", .keyword_unsigned },
+ .{ "void", .keyword_void },
+ .{ "volatile", .keyword_volatile },
+ .{ "while", .keyword_while },
+ .{ "__typeof__", .keyword_typeof2 },
+ .{ "__typeof", .keyword_typeof1 },
+
+ // ISO C99
+ .{ "_Bool", .keyword_bool },
+ .{ "_Complex", .keyword_complex },
+ .{ "_Imaginary", .keyword_imaginary },
+ .{ "inline", .keyword_inline },
+ .{ "restrict", .keyword_restrict },
+
+ // ISO C11
+ .{ "_Alignas", .keyword_alignas },
+ .{ "_Alignof", .keyword_alignof },
+ .{ "_Atomic", .keyword_atomic },
+ .{ "_Generic", .keyword_generic },
+ .{ "_Noreturn", .keyword_noreturn },
+ .{ "_Static_assert", .keyword_static_assert },
+ .{ "_Thread_local", .keyword_thread_local },
+
+ // ISO C23
+ .{ "_BitInt", .keyword_bit_int },
+ .{ "alignas", .keyword_c23_alignas },
+ .{ "alignof", .keyword_c23_alignof },
+ .{ "bool", .keyword_c23_bool },
+ .{ "static_assert", .keyword_c23_static_assert },
+ .{ "thread_local", .keyword_c23_thread_local },
+ .{ "constexpr", .keyword_constexpr },
+ .{ "true", .keyword_true },
+ .{ "false", .keyword_false },
+ .{ "nullptr", .keyword_nullptr },
+
+ // Preprocessor directives
+ .{ "include", .keyword_include },
+ .{ "include_next", .keyword_include_next },
+ .{ "embed", .keyword_embed },
+ .{ "define", .keyword_define },
+ .{ "defined", .keyword_defined },
+ .{ "undef", .keyword_undef },
+ .{ "ifdef", .keyword_ifdef },
+ .{ "ifndef", .keyword_ifndef },
+ .{ "elif", .keyword_elif },
+ .{ "elifdef", .keyword_elifdef },
+ .{ "elifndef", .keyword_elifndef },
+ .{ "endif", .keyword_endif },
+ .{ "error", .keyword_error },
+ .{ "warning", .keyword_warning },
+ .{ "pragma", .keyword_pragma },
+ .{ "line", .keyword_line },
+ .{ "__VA_ARGS__", .keyword_va_args },
+ .{ "__func__", .macro_func },
+ .{ "__FUNCTION__", .macro_function },
+ .{ "__PRETTY_FUNCTION__", .macro_pretty_func },
+
+ // gcc keywords
+ .{ "__auto_type", .keyword_auto_type },
+ .{ "__const", .keyword_const1 },
+ .{ "__const__", .keyword_const2 },
+ .{ "__inline", .keyword_inline1 },
+ .{ "__inline__", .keyword_inline2 },
+ .{ "__volatile", .keyword_volatile1 },
+ .{ "__volatile__", .keyword_volatile2 },
+ .{ "__restrict", .keyword_restrict1 },
+ .{ "__restrict__", .keyword_restrict2 },
+ .{ "__alignof", .keyword_alignof1 },
+ .{ "__alignof__", .keyword_alignof2 },
+ .{ "typeof", .keyword_typeof },
+ .{ "__attribute", .keyword_attribute1 },
+ .{ "__attribute__", .keyword_attribute2 },
+ .{ "__extension__", .keyword_extension },
+ .{ "asm", .keyword_asm },
+ .{ "__asm", .keyword_asm1 },
+ .{ "__asm__", .keyword_asm2 },
+ .{ "__float80", .keyword_float80 },
+ .{ "__float128", .keyword_float128 },
+ .{ "__int128", .keyword_int128 },
+ .{ "__imag", .keyword_imag1 },
+ .{ "__imag__", .keyword_imag2 },
+ .{ "__real", .keyword_real1 },
+ .{ "__real__", .keyword_real2 },
+ .{ "_Float16", .keyword_float16 },
+
+ // clang keywords
+ .{ "__fp16", .keyword_fp16 },
+
+ // ms keywords
+ .{ "__declspec", .keyword_declspec },
+ .{ "__int64", .keyword_int64 },
+ .{ "_int64", .keyword_int64_2 },
+ .{ "__int32", .keyword_int32 },
+ .{ "_int32", .keyword_int32_2 },
+ .{ "__int16", .keyword_int16 },
+ .{ "_int16", .keyword_int16_2 },
+ .{ "__int8", .keyword_int8 },
+ .{ "_int8", .keyword_int8_2 },
+ .{ "__stdcall", .keyword_stdcall },
+ .{ "_stdcall", .keyword_stdcall2 },
+ .{ "__thiscall", .keyword_thiscall },
+ .{ "_thiscall", .keyword_thiscall2 },
+ .{ "__vectorcall", .keyword_vectorcall },
+ .{ "_vectorcall", .keyword_vectorcall2 },
+
+ // builtins that require special parsing
+ .{ "__builtin_choose_expr", .builtin_choose_expr },
+ .{ "__builtin_va_arg", .builtin_va_arg },
+ .{ "__builtin_offsetof", .builtin_offsetof },
+ .{ "__builtin_bitoffsetof", .builtin_bitoffsetof },
+ .{ "__builtin_types_compatible_p", .builtin_types_compatible_p },
+ });
+};
+
+buf: []const u8,
+index: u32 = 0,
+source: Source.Id,
+comp: *const Compilation,
+line: u32 = 1,
+
+pub fn next(self: *Tokenizer) Token {
+ var state: enum {
+ start,
+ whitespace,
+ u,
+ u8,
+ U,
+ L,
+ string_literal,
+ char_literal_start,
+ char_literal,
+ escape_sequence,
+ octal_escape,
+ hex_escape,
+ unicode_escape,
+ identifier,
+ extended_identifier,
+ equal,
+ bang,
+ pipe,
+ colon,
+ percent,
+ asterisk,
+ plus,
+ angle_bracket_left,
+ angle_bracket_angle_bracket_left,
+ angle_bracket_right,
+ angle_bracket_angle_bracket_right,
+ caret,
+ period,
+ period2,
+ minus,
+ slash,
+ ampersand,
+ hash,
+ hash_digraph,
+ hash_hash_digraph_partial,
+ line_comment,
+ multi_line_comment,
+ multi_line_comment_asterisk,
+ multi_line_comment_done,
+ pp_num,
+ pp_num_exponent,
+ pp_num_digit_separator,
+ } = .start;
+
+ var start = self.index;
+ var id: Token.Id = .eof;
+
+ var return_state = state;
+ var counter: u32 = 0;
+ var codepoint_len: u3 = undefined;
+ while (self.index < self.buf.len) : (self.index += codepoint_len) {
+ // Source files get checked for valid utf-8 before being tokenized so it is safe to use
+ // these versions.
+ codepoint_len = unicode.utf8ByteSequenceLength_unsafe(self.buf[self.index]);
+ const c: u21 = switch (codepoint_len) {
+ 1 => @as(u21, self.buf[self.index]),
+ 2 => unicode.utf8Decode2_unsafe(self.buf[self.index..]),
+ 3 => unicode.utf8Decode3_unsafe(self.buf[self.index..]),
+ 4 => unicode.utf8Decode4_unsafe(self.buf[self.index..]),
+ else => unreachable,
+ };
+ switch (state) {
+ .start => switch (c) {
+ '\n' => {
+ id = .nl;
+ self.index += 1;
+ self.line += 1;
+ break;
+ },
+ '"' => {
+ id = .string_literal;
+ state = .string_literal;
+ },
+ '\'' => {
+ id = .char_literal;
+ state = .char_literal_start;
+ },
+ 'u' => state = .u,
+ 'U' => state = .U,
+ 'L' => state = .L,
+ 'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_' => state = .identifier,
+ '=' => state = .equal,
+ '!' => state = .bang,
+ '|' => state = .pipe,
+ '(' => {
+ id = .l_paren;
+ self.index += 1;
+ break;
+ },
+ ')' => {
+ id = .r_paren;
+ self.index += 1;
+ break;
+ },
+ '[' => {
+ id = .l_bracket;
+ self.index += 1;
+ break;
+ },
+ ']' => {
+ id = .r_bracket;
+ self.index += 1;
+ break;
+ },
+ ';' => {
+ id = .semicolon;
+ self.index += 1;
+ break;
+ },
+ ',' => {
+ id = .comma;
+ self.index += 1;
+ break;
+ },
+ '?' => {
+ id = .question_mark;
+ self.index += 1;
+ break;
+ },
+ ':' => state = .colon,
+ '%' => state = .percent,
+ '*' => state = .asterisk,
+ '+' => state = .plus,
+ '<' => state = .angle_bracket_left,
+ '>' => state = .angle_bracket_right,
+ '^' => state = .caret,
+ '{' => {
+ id = .l_brace;
+ self.index += 1;
+ break;
+ },
+ '}' => {
+ id = .r_brace;
+ self.index += 1;
+ break;
+ },
+ '~' => {
+ id = .tilde;
+ self.index += 1;
+ break;
+ },
+ '.' => state = .period,
+ '-' => state = .minus,
+ '/' => state = .slash,
+ '&' => state = .ampersand,
+ '#' => state = .hash,
+ '0'...'9' => state = .pp_num,
+ '\t', '\x0B', '\x0C', ' ' => state = .whitespace,
+ else => if (Token.mayAppearInIdent(self.comp, c, .start)) {
+ state = .extended_identifier;
+ } else {
+ id = .invalid;
+ self.index += codepoint_len;
+ break;
+ },
+ },
+ .whitespace => switch (c) {
+ '\t', '\x0B', '\x0C', ' ' => {},
+ else => {
+ id = .whitespace;
+ break;
+ },
+ },
+ .u => switch (c) {
+ '8' => {
+ state = .u8;
+ },
+ '\'' => {
+ id = .char_literal_utf_16;
+ state = .char_literal_start;
+ },
+ '\"' => {
+ id = .string_literal_utf_16;
+ state = .string_literal;
+ },
+ else => {
+ codepoint_len = 0;
+ state = .identifier;
+ },
+ },
+ .u8 => switch (c) {
+ '\"' => {
+ id = .string_literal_utf_8;
+ state = .string_literal;
+ },
+ '\'' => {
+ id = .char_literal_utf_8;
+ state = .char_literal_start;
+ },
+ else => {
+ codepoint_len = 0;
+ state = .identifier;
+ },
+ },
+ .U => switch (c) {
+ '\'' => {
+ id = .char_literal_utf_32;
+ state = .char_literal_start;
+ },
+ '\"' => {
+ id = .string_literal_utf_32;
+ state = .string_literal;
+ },
+ else => {
+ codepoint_len = 0;
+ state = .identifier;
+ },
+ },
+ .L => switch (c) {
+ '\'' => {
+ id = .char_literal_wide;
+ state = .char_literal_start;
+ },
+ '\"' => {
+ id = .string_literal_wide;
+ state = .string_literal;
+ },
+ else => {
+ codepoint_len = 0;
+ state = .identifier;
+ },
+ },
+ .string_literal => switch (c) {
+ '\\' => {
+ return_state = .string_literal;
+ state = .escape_sequence;
+ },
+ '"' => {
+ self.index += 1;
+ break;
+ },
+ '\n' => {
+ id = .invalid;
+ break;
+ },
+ '\r' => unreachable,
+ else => {},
+ },
+ .char_literal_start => switch (c) {
+ '\\' => {
+ return_state = .char_literal;
+ state = .escape_sequence;
+ },
+
+ '\'', '\n' => {
+ id = .invalid;
+ break;
+ },
+ else => {
+ state = .char_literal;
+ },
+ },
+ .char_literal => switch (c) {
+ '\\' => {
+ return_state = .char_literal;
+ state = .escape_sequence;
+ },
+ '\'' => {
+ self.index += 1;
+ break;
+ },
+ '\n' => {
+ id = .invalid;
+ break;
+ },
+ else => {},
+ },
+ .escape_sequence => switch (c) {
+ '\'', '"', '?', '\\', 'a', 'b', 'e', 'f', 'n', 'r', 't', 'v' => {
+ state = return_state;
+ },
+ '\n' => {
+ state = return_state;
+ self.line += 1;
+ },
+ '0'...'7' => {
+ counter = 1;
+ state = .octal_escape;
+ },
+ 'x' => state = .hex_escape,
+ 'u' => {
+ counter = 4;
+ state = .unicode_escape;
+ },
+ 'U' => {
+ counter = 8;
+ state = .unicode_escape;
+ },
+ else => {
+ id = .invalid;
+ break;
+ },
+ },
+ .octal_escape => switch (c) {
+ '0'...'7' => {
+ counter += 1;
+ if (counter == 3) state = return_state;
+ },
+ else => {
+ codepoint_len = 0;
+ state = return_state;
+ },
+ },
+ .hex_escape => switch (c) {
+ '0'...'9', 'a'...'f', 'A'...'F' => {},
+ else => {
+ codepoint_len = 0;
+ state = return_state;
+ },
+ },
+ .unicode_escape => switch (c) {
+ '0'...'9', 'a'...'f', 'A'...'F' => {
+ counter -= 1;
+ if (counter == 0) state = return_state;
+ },
+ else => {
+ id = .invalid;
+ break;
+ },
+ },
+ .identifier, .extended_identifier => switch (c) {
+ 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
+ else => {
+ if (!Token.mayAppearInIdent(self.comp, c, .inside)) {
+ id = if (state == .identifier) Token.getTokenId(self.comp, self.buf[start..self.index]) else .extended_identifier;
+ break;
+ }
+ state = .extended_identifier;
+ },
+ },
+ .equal => switch (c) {
+ '=' => {
+ id = .equal_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .equal;
+ break;
+ },
+ },
+ .bang => switch (c) {
+ '=' => {
+ id = .bang_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .bang;
+ break;
+ },
+ },
+ .pipe => switch (c) {
+ '=' => {
+ id = .pipe_equal;
+ self.index += 1;
+ break;
+ },
+ '|' => {
+ id = .pipe_pipe;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .pipe;
+ break;
+ },
+ },
+ .colon => switch (c) {
+ '>' => {
+ if (self.comp.langopts.hasDigraphs()) {
+ id = .r_bracket;
+ self.index += 1;
+ } else {
+ id = .colon;
+ }
+ break;
+ },
+ ':' => {
+ if (self.comp.langopts.standard.atLeast(.c2x)) {
+ id = .colon_colon;
+ self.index += 1;
+ break;
+ } else {
+ id = .colon;
+ break;
+ }
+ },
+ else => {
+ id = .colon;
+ break;
+ },
+ },
+ .percent => switch (c) {
+ '=' => {
+ id = .percent_equal;
+ self.index += 1;
+ break;
+ },
+ '>' => {
+ if (self.comp.langopts.hasDigraphs()) {
+ id = .r_brace;
+ self.index += 1;
+ } else {
+ id = .percent;
+ }
+ break;
+ },
+ ':' => {
+ if (self.comp.langopts.hasDigraphs()) {
+ state = .hash_digraph;
+ } else {
+ id = .percent;
+ break;
+ }
+ },
+ else => {
+ id = .percent;
+ break;
+ },
+ },
+ .asterisk => switch (c) {
+ '=' => {
+ id = .asterisk_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .asterisk;
+ break;
+ },
+ },
+ .plus => switch (c) {
+ '=' => {
+ id = .plus_equal;
+ self.index += 1;
+ break;
+ },
+ '+' => {
+ id = .plus_plus;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .plus;
+ break;
+ },
+ },
+ .angle_bracket_left => switch (c) {
+ '<' => state = .angle_bracket_angle_bracket_left,
+ '=' => {
+ id = .angle_bracket_left_equal;
+ self.index += 1;
+ break;
+ },
+ ':' => {
+ if (self.comp.langopts.hasDigraphs()) {
+ id = .l_bracket;
+ self.index += 1;
+ } else {
+ id = .angle_bracket_left;
+ }
+ break;
+ },
+ '%' => {
+ if (self.comp.langopts.hasDigraphs()) {
+ id = .l_brace;
+ self.index += 1;
+ } else {
+ id = .angle_bracket_left;
+ }
+ break;
+ },
+ else => {
+ id = .angle_bracket_left;
+ break;
+ },
+ },
+ .angle_bracket_angle_bracket_left => switch (c) {
+ '=' => {
+ id = .angle_bracket_angle_bracket_left_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .angle_bracket_angle_bracket_left;
+ break;
+ },
+ },
+ .angle_bracket_right => switch (c) {
+ '>' => state = .angle_bracket_angle_bracket_right,
+ '=' => {
+ id = .angle_bracket_right_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .angle_bracket_right;
+ break;
+ },
+ },
+ .angle_bracket_angle_bracket_right => switch (c) {
+ '=' => {
+ id = .angle_bracket_angle_bracket_right_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .angle_bracket_angle_bracket_right;
+ break;
+ },
+ },
+ .caret => switch (c) {
+ '=' => {
+ id = .caret_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .caret;
+ break;
+ },
+ },
+ .period => switch (c) {
+ '.' => state = .period2,
+ '0'...'9' => state = .pp_num,
+ else => {
+ id = .period;
+ break;
+ },
+ },
+ .period2 => switch (c) {
+ '.' => {
+ id = .ellipsis;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .period;
+ self.index -= 1;
+ break;
+ },
+ },
+ .minus => switch (c) {
+ '>' => {
+ id = .arrow;
+ self.index += 1;
+ break;
+ },
+ '=' => {
+ id = .minus_equal;
+ self.index += 1;
+ break;
+ },
+ '-' => {
+ id = .minus_minus;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .minus;
+ break;
+ },
+ },
+ .ampersand => switch (c) {
+ '&' => {
+ id = .ampersand_ampersand;
+ self.index += 1;
+ break;
+ },
+ '=' => {
+ id = .ampersand_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .ampersand;
+ break;
+ },
+ },
+ .hash => switch (c) {
+ '#' => {
+ id = .hash_hash;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .hash;
+ break;
+ },
+ },
+ .hash_digraph => switch (c) {
+ '%' => state = .hash_hash_digraph_partial,
+ else => {
+ id = .hash;
+ break;
+ },
+ },
+ .hash_hash_digraph_partial => switch (c) {
+ ':' => {
+ id = .hash_hash;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .hash;
+ self.index -= 1; // re-tokenize the percent
+ break;
+ },
+ },
+ .slash => switch (c) {
+ '/' => state = .line_comment,
+ '*' => state = .multi_line_comment,
+ '=' => {
+ id = .slash_equal;
+ self.index += 1;
+ break;
+ },
+ else => {
+ id = .slash;
+ break;
+ },
+ },
+ .line_comment => switch (c) {
+ '\n' => {
+ self.index -= 1;
+ state = .start;
+ },
+ else => {},
+ },
+ .multi_line_comment => switch (c) {
+ '*' => state = .multi_line_comment_asterisk,
+ '\n' => self.line += 1,
+ else => {},
+ },
+ .multi_line_comment_asterisk => switch (c) {
+ '/' => state = .multi_line_comment_done,
+ '\n' => {
+ self.line += 1;
+ state = .multi_line_comment;
+ },
+ '*' => {},
+ else => state = .multi_line_comment,
+ },
+ .multi_line_comment_done => switch (c) {
+ '\n' => {
+ start = self.index;
+ id = .nl;
+ self.index += 1;
+ self.line += 1;
+ break;
+ },
+ '\r' => unreachable,
+ '\t', '\x0B', '\x0C', ' ' => {
+ start = self.index;
+ state = .whitespace;
+ },
+ else => {
+ id = .whitespace;
+ break;
+ },
+ },
+ .pp_num => switch (c) {
+ 'a'...'d',
+ 'A'...'D',
+ 'f'...'o',
+ 'F'...'O',
+ 'q'...'z',
+ 'Q'...'Z',
+ '0'...'9',
+ '_',
+ '.',
+ => {},
+ 'e', 'E', 'p', 'P' => state = .pp_num_exponent,
+ '\'' => if (self.comp.langopts.standard.atLeast(.c2x)) {
+ state = .pp_num_digit_separator;
+ } else {
+ id = .pp_num;
+ break;
+ },
+ else => {
+ id = .pp_num;
+ break;
+ },
+ },
+ .pp_num_digit_separator => switch (c) {
+ 'a'...'d',
+ 'A'...'D',
+ 'f'...'o',
+ 'F'...'O',
+ 'q'...'z',
+ 'Q'...'Z',
+ '0'...'9',
+ '_',
+ => state = .pp_num,
+ else => {
+ self.index -= 1;
+ id = .pp_num;
+ break;
+ },
+ },
+ .pp_num_exponent => switch (c) {
+ 'a'...'z',
+ 'A'...'Z',
+ '0'...'9',
+ '_',
+ '.',
+ '+',
+ '-',
+ => state = .pp_num,
+ else => {
+ id = .pp_num;
+ break;
+ },
+ },
+ }
+ } else if (self.index == self.buf.len) {
+ switch (state) {
+ .start, .line_comment => {},
+ .u, .u8, .U, .L, .identifier => id = Token.getTokenId(self.comp, self.buf[start..self.index]),
+ .extended_identifier => id = .extended_identifier,
+ .period2,
+ .string_literal,
+ .char_literal_start,
+ .char_literal,
+ .escape_sequence,
+ .octal_escape,
+ .hex_escape,
+ .unicode_escape,
+ .multi_line_comment,
+ .multi_line_comment_asterisk,
+ => id = .invalid,
+
+ .whitespace => id = .whitespace,
+ .multi_line_comment_done => id = .whitespace,
+
+ .equal => id = .equal,
+ .bang => id = .bang,
+ .minus => id = .minus,
+ .slash => id = .slash,
+ .ampersand => id = .ampersand,
+ .hash => id = .hash,
+ .period => id = .period,
+ .pipe => id = .pipe,
+ .angle_bracket_angle_bracket_right => id = .angle_bracket_angle_bracket_right,
+ .angle_bracket_right => id = .angle_bracket_right,
+ .angle_bracket_angle_bracket_left => id = .angle_bracket_angle_bracket_left,
+ .angle_bracket_left => id = .angle_bracket_left,
+ .plus => id = .plus,
+ .colon => id = .colon,
+ .percent => id = .percent,
+ .caret => id = .caret,
+ .asterisk => id = .asterisk,
+ .hash_digraph => id = .hash,
+ .hash_hash_digraph_partial => {
+ id = .hash;
+ self.index -= 1; // re-tokenize the percent
+ },
+ .pp_num, .pp_num_exponent, .pp_num_digit_separator => id = .pp_num,
+ }
+ }
+
+ return .{
+ .id = id,
+ .start = start,
+ .end = self.index,
+ .line = self.line,
+ .source = self.source,
+ };
+}
+
+pub fn nextNoWS(self: *Tokenizer) Token {
+ var tok = self.next();
+ while (tok.id == .whitespace) tok = self.next();
+ return tok;
+}
+
+test "operators" {
+ try expectTokens(
+ \\ ! != | || |= = ==
+ \\ ( ) { } [ ] . .. ...
+ \\ ^ ^= + ++ += - -- -=
+ \\ * *= % %= -> : ; / /=
+ \\ , & && &= ? < <= <<
+ \\ <<= > >= >> >>= ~ # ##
+ \\
+ , &.{
+ .bang,
+ .bang_equal,
+ .pipe,
+ .pipe_pipe,
+ .pipe_equal,
+ .equal,
+ .equal_equal,
+ .nl,
+ .l_paren,
+ .r_paren,
+ .l_brace,
+ .r_brace,
+ .l_bracket,
+ .r_bracket,
+ .period,
+ .period,
+ .period,
+ .ellipsis,
+ .nl,
+ .caret,
+ .caret_equal,
+ .plus,
+ .plus_plus,
+ .plus_equal,
+ .minus,
+ .minus_minus,
+ .minus_equal,
+ .nl,
+ .asterisk,
+ .asterisk_equal,
+ .percent,
+ .percent_equal,
+ .arrow,
+ .colon,
+ .semicolon,
+ .slash,
+ .slash_equal,
+ .nl,
+ .comma,
+ .ampersand,
+ .ampersand_ampersand,
+ .ampersand_equal,
+ .question_mark,
+ .angle_bracket_left,
+ .angle_bracket_left_equal,
+ .angle_bracket_angle_bracket_left,
+ .nl,
+ .angle_bracket_angle_bracket_left_equal,
+ .angle_bracket_right,
+ .angle_bracket_right_equal,
+ .angle_bracket_angle_bracket_right,
+ .angle_bracket_angle_bracket_right_equal,
+ .tilde,
+ .hash,
+ .hash_hash,
+ .nl,
+ });
+}
+
+test "keywords" {
+ try expectTokens(
+ \\auto __auto_type break case char const continue default do
+ \\double else enum extern float for goto if int
+ \\long register return short signed sizeof static
+ \\struct switch typedef union unsigned void volatile
+ \\while _Bool _Complex _Imaginary inline restrict _Alignas
+ \\_Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local
+ \\__attribute __attribute__
+ \\
+ , &.{
+ .keyword_auto,
+ .keyword_auto_type,
+ .keyword_break,
+ .keyword_case,
+ .keyword_char,
+ .keyword_const,
+ .keyword_continue,
+ .keyword_default,
+ .keyword_do,
+ .nl,
+ .keyword_double,
+ .keyword_else,
+ .keyword_enum,
+ .keyword_extern,
+ .keyword_float,
+ .keyword_for,
+ .keyword_goto,
+ .keyword_if,
+ .keyword_int,
+ .nl,
+ .keyword_long,
+ .keyword_register,
+ .keyword_return,
+ .keyword_short,
+ .keyword_signed,
+ .keyword_sizeof,
+ .keyword_static,
+ .nl,
+ .keyword_struct,
+ .keyword_switch,
+ .keyword_typedef,
+ .keyword_union,
+ .keyword_unsigned,
+ .keyword_void,
+ .keyword_volatile,
+ .nl,
+ .keyword_while,
+ .keyword_bool,
+ .keyword_complex,
+ .keyword_imaginary,
+ .keyword_inline,
+ .keyword_restrict,
+ .keyword_alignas,
+ .nl,
+ .keyword_alignof,
+ .keyword_atomic,
+ .keyword_generic,
+ .keyword_noreturn,
+ .keyword_static_assert,
+ .keyword_thread_local,
+ .nl,
+ .keyword_attribute1,
+ .keyword_attribute2,
+ .nl,
+ });
+}
+
+test "preprocessor keywords" {
+ try expectTokens(
+ \\#include
+ \\#include_next
+ \\#embed
+ \\#define
+ \\#ifdef
+ \\#ifndef
+ \\#error
+ \\#pragma
+ \\
+ , &.{
+ .hash,
+ .keyword_include,
+ .nl,
+ .hash,
+ .keyword_include_next,
+ .nl,
+ .hash,
+ .keyword_embed,
+ .nl,
+ .hash,
+ .keyword_define,
+ .nl,
+ .hash,
+ .keyword_ifdef,
+ .nl,
+ .hash,
+ .keyword_ifndef,
+ .nl,
+ .hash,
+ .keyword_error,
+ .nl,
+ .hash,
+ .keyword_pragma,
+ .nl,
+ });
+}
+
+test "line continuation" {
+ try expectTokens(
+ \\#define foo \
+ \\ bar
+ \\"foo\
+ \\ bar"
+ \\#define "foo"
+ \\ "bar"
+ \\#define "foo" \
+ \\ "bar"
+ , &.{
+ .hash,
+ .keyword_define,
+ .identifier,
+ .identifier,
+ .nl,
+ .string_literal,
+ .nl,
+ .hash,
+ .keyword_define,
+ .string_literal,
+ .nl,
+ .string_literal,
+ .nl,
+ .hash,
+ .keyword_define,
+ .string_literal,
+ .string_literal,
+ });
+}
+
+test "string prefix" {
+ try expectTokens(
+ \\"foo"
+ \\u"foo"
+ \\u8"foo"
+ \\U"foo"
+ \\L"foo"
+ \\'foo'
+ \\u8'A'
+ \\u'foo'
+ \\U'foo'
+ \\L'foo'
+ \\
+ , &.{
+ .string_literal,
+ .nl,
+ .string_literal_utf_16,
+ .nl,
+ .string_literal_utf_8,
+ .nl,
+ .string_literal_utf_32,
+ .nl,
+ .string_literal_wide,
+ .nl,
+ .char_literal,
+ .nl,
+ .char_literal_utf_8,
+ .nl,
+ .char_literal_utf_16,
+ .nl,
+ .char_literal_utf_32,
+ .nl,
+ .char_literal_wide,
+ .nl,
+ });
+}
+
+test "num suffixes" {
+ try expectTokens(
+ \\ 1.0f 1.0L 1.0 .0 1. 0x1p0f 0X1p0
+ \\ 0l 0lu 0ll 0llu 0
+ \\ 1u 1ul 1ull 1
+ \\ 1.0i 1.0I
+ \\ 1.0if 1.0If 1.0fi 1.0fI
+ \\ 1.0il 1.0Il 1.0li 1.0lI
+ \\
+ , &.{
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .nl,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .nl,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .nl,
+ .pp_num,
+ .pp_num,
+ .nl,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .nl,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .pp_num,
+ .nl,
+ });
+}
+
+test "comments" {
+ try expectTokens(
+ \\//foo
+ \\#foo
+ , &.{
+ .nl,
+ .hash,
+ .identifier,
+ });
+}
+
+test "extended identifiers" {
+ try expectTokens("๐ช๐ป๐ธ๐ฌ๐ฌ", &.{.extended_identifier});
+ try expectTokens("u๐ช๐ป๐ธ๐ฌ๐ฌ", &.{.extended_identifier});
+ try expectTokens("u8๐ช๐ป๐ธ๐ฌ๐ฌ", &.{.extended_identifier});
+ try expectTokens("U๐ช๐ป๐ธ๐ฌ๐ฌ", &.{.extended_identifier});
+ try expectTokens("L๐ช๐ป๐ธ๐ฌ๐ฌ", &.{.extended_identifier});
+ try expectTokens("1โข", &.{ .pp_num, .extended_identifier });
+ try expectTokens("1.โข", &.{ .pp_num, .extended_identifier });
+ try expectTokens("..โข", &.{ .period, .period, .extended_identifier });
+ try expectTokens("0โข", &.{ .pp_num, .extended_identifier });
+ try expectTokens("0b\u{E0000}", &.{ .pp_num, .extended_identifier });
+ try expectTokens("0b0\u{E0000}", &.{ .pp_num, .extended_identifier });
+ try expectTokens("01\u{E0000}", &.{ .pp_num, .extended_identifier });
+ try expectTokens("010\u{E0000}", &.{ .pp_num, .extended_identifier });
+ try expectTokens("0x\u{E0000}", &.{ .pp_num, .extended_identifier });
+ try expectTokens("0x0\u{E0000}", &.{ .pp_num, .extended_identifier });
+ try expectTokens("\"\\0\u{E0000}\"", &.{.string_literal});
+ try expectTokens("\"\\x\u{E0000}\"", &.{.string_literal});
+ try expectTokens("\"\\u\u{E0000}\"", &.{ .invalid, .extended_identifier, .invalid });
+ try expectTokens("1e\u{E0000}", &.{ .pp_num, .extended_identifier });
+ try expectTokens("1e1\u{E0000}", &.{ .pp_num, .extended_identifier });
+}
+
+test "digraphs" {
+ try expectTokens("%:<::><%%>%:%:", &.{ .hash, .l_bracket, .r_bracket, .l_brace, .r_brace, .hash_hash });
+ try expectTokens("\"%:<::><%%>%:%:\"", &.{.string_literal});
+ try expectTokens("%:%42 %:%", &.{ .hash, .percent, .pp_num, .hash, .percent });
+}
+
+test "C23 keywords" {
+ try expectTokensExtra("true false alignas alignof bool static_assert thread_local nullptr", &.{
+ .keyword_true,
+ .keyword_false,
+ .keyword_c23_alignas,
+ .keyword_c23_alignof,
+ .keyword_c23_bool,
+ .keyword_c23_static_assert,
+ .keyword_c23_thread_local,
+ .keyword_nullptr,
+ }, .c2x);
+}
+
+fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, standard: ?LangOpts.Standard) !void {
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+ if (standard) |provided| {
+ comp.langopts.standard = provided;
+ }
+ const source = try comp.addSourceFromBuffer("path", contents);
+ var tokenizer = Tokenizer{
+ .buf = source.buf,
+ .source = source.id,
+ .comp = &comp,
+ };
+ var i: usize = 0;
+ while (i < expected_tokens.len) {
+ const token = tokenizer.next();
+ if (token.id == .whitespace) continue;
+ const expected_token_id = expected_tokens[i];
+ i += 1;
+ if (!std.meta.eql(token.id, expected_token_id)) {
+ std.debug.print("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
+ return error.TokensDoNotEqual;
+ }
+ }
+ const last_token = tokenizer.next();
+ try std.testing.expect(last_token.id == .eof);
+}
+
+fn expectTokens(contents: []const u8, expected_tokens: []const Token.Id) !void {
+ return expectTokensExtra(contents, expected_tokens, null);
+}
deps/aro/Toolchain.zig
@@ -0,0 +1,493 @@
+const std = @import("std");
+const Driver = @import("Driver.zig");
+const Compilation = @import("Compilation.zig");
+const util = @import("util.zig");
+const mem = std.mem;
+const system_defaults = @import("system_defaults");
+const target_util = @import("target.zig");
+const Linux = @import("toolchains/Linux.zig");
+const Multilib = @import("Driver/Multilib.zig");
+const Filesystem = @import("Driver/Filesystem.zig").Filesystem;
+
+const Toolchain = @This();
+
+pub const PathList = std.ArrayListUnmanaged([]const u8);
+
+pub const RuntimeLibKind = enum {
+ compiler_rt,
+ libgcc,
+};
+
+pub const FileKind = enum {
+ object,
+ static,
+ shared,
+};
+
+pub const LibGCCKind = enum {
+ unspecified,
+ static,
+ shared,
+};
+
+pub const UnwindLibKind = enum {
+ none,
+ compiler_rt,
+ libgcc,
+};
+
+const Inner = union(enum) {
+ uninitialized,
+ linux: Linux,
+ unknown: void,
+
+ fn deinit(self: *Inner, allocator: mem.Allocator) void {
+ switch (self.*) {
+ .linux => |*linux| linux.deinit(allocator),
+ .uninitialized, .unknown => {},
+ }
+ }
+};
+
+filesystem: Filesystem = .{ .real = {} },
+driver: *Driver,
+arena: mem.Allocator,
+
+/// The list of toolchain specific path prefixes to search for libraries.
+library_paths: PathList = .{},
+
+/// The list of toolchain specific path prefixes to search for files.
+file_paths: PathList = .{},
+
+/// The list of toolchain specific path prefixes to search for programs.
+program_paths: PathList = .{},
+
+selected_multilib: Multilib = .{},
+
+inner: Inner = .{ .uninitialized = {} },
+
+pub fn getTarget(tc: *const Toolchain) std.Target {
+ return tc.driver.comp.target;
+}
+
+fn getDefaultLinker(tc: *const Toolchain) []const u8 {
+ return switch (tc.inner) {
+ .uninitialized => unreachable,
+ .linux => |linux| linux.getDefaultLinker(tc.getTarget()),
+ .unknown => "ld",
+ };
+}
+
+/// Call this after driver has finished parsing command line arguments to find the toolchain
+pub fn discover(tc: *Toolchain) !void {
+ if (tc.inner != .uninitialized) return;
+
+ const target = tc.getTarget();
+ tc.inner = switch (target.os.tag) {
+ .elfiamcu,
+ .linux,
+ => if (target.cpu.arch == .hexagon)
+ .{ .unknown = {} } // TODO
+ else if (target.cpu.arch.isMIPS())
+ .{ .unknown = {} } // TODO
+ else if (target.cpu.arch.isPPC())
+ .{ .unknown = {} } // TODO
+ else if (target.cpu.arch == .ve)
+ .{ .unknown = {} } // TODO
+ else
+ .{ .linux = .{} },
+ else => .{ .unknown = {} }, // TODO
+ };
+ return switch (tc.inner) {
+ .uninitialized => unreachable,
+ .linux => |*linux| linux.discover(tc),
+ .unknown => {},
+ };
+}
+
+pub fn deinit(tc: *Toolchain) void {
+ const gpa = tc.driver.comp.gpa;
+ tc.inner.deinit(gpa);
+
+ tc.library_paths.deinit(gpa);
+ tc.file_paths.deinit(gpa);
+ tc.program_paths.deinit(gpa);
+}
+
+/// Write linker path to `buf` and return a slice of it
+pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
+ // --ld-path= takes precedence over -fuse-ld= and specifies the executable
+ // name. -B, COMPILER_PATH and PATH are consulted if the value does not
+ // contain a path component separator.
+ // -fuse-ld=lld can be used with --ld-path= to indicate that the binary
+ // that --ld-path= points to is lld.
+ const use_linker = tc.driver.use_linker orelse system_defaults.linker;
+
+ if (tc.driver.linker_path) |ld_path| {
+ var path = ld_path;
+ if (path.len > 0) {
+ if (std.fs.path.dirname(path) == null) {
+ path = tc.getProgramPath(path, buf);
+ }
+ if (tc.filesystem.canExecute(path)) {
+ return path;
+ }
+ }
+ return tc.driver.fatal(
+ "invalid linker name in argument '--ld-path={s}'",
+ .{path},
+ );
+ }
+
+ // If we're passed -fuse-ld= with no argument, or with the argument ld,
+ // then use whatever the default system linker is.
+ if (use_linker.len == 0 or mem.eql(u8, use_linker, "ld")) {
+ const default = tc.getDefaultLinker();
+ if (std.fs.path.isAbsolute(default)) return default;
+ return tc.getProgramPath(default, buf);
+ }
+
+ // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
+ // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
+ // to a relative path is surprising. This is more complex due to priorities
+ // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
+ if (mem.indexOfScalar(u8, use_linker, '/') != null) {
+ try tc.driver.comp.diag.add(.{ .tag = .fuse_ld_path }, &.{});
+ }
+
+ if (std.fs.path.isAbsolute(use_linker)) {
+ if (tc.filesystem.canExecute(use_linker)) {
+ return use_linker;
+ }
+ } else {
+ var linker_name = try std.ArrayList(u8).initCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker
+ defer linker_name.deinit();
+ if (tc.getTarget().isDarwin()) {
+ linker_name.appendSliceAssumeCapacity("ld64.");
+ } else {
+ linker_name.appendSliceAssumeCapacity("ld.");
+ }
+ linker_name.appendSliceAssumeCapacity(use_linker);
+ const linker_path = tc.getProgramPath(linker_name.items, buf);
+ if (tc.filesystem.canExecute(linker_path)) {
+ return linker_path;
+ }
+ }
+
+ if (tc.driver.use_linker) |linker| {
+ return tc.driver.fatal(
+ "invalid linker name in argument '-fuse-ld={s}'",
+ .{linker},
+ );
+ }
+ const default_linker = tc.getDefaultLinker();
+ return tc.getProgramPath(default_linker, buf);
+}
+
+const TargetSpecificToolName = std.BoundedArray(u8, 64);
+
+/// If an explicit target is provided, also check the prefixed tool-specific name
+/// TODO: this isn't exactly right since our target names don't necessarily match up
+/// with GCC's.
+/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools
+fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, target_specific: *TargetSpecificToolName) std.BoundedArray([]const u8, 2) {
+ var possible_names: std.BoundedArray([]const u8, 2) = .{};
+ if (raw_triple) |triple| {
+ const w = target_specific.writer();
+ if (w.print("{s}-{s}", .{ triple, name })) {
+ possible_names.appendAssumeCapacity(target_specific.constSlice());
+ } else |_| {}
+ }
+ possible_names.appendAssumeCapacity(name);
+
+ return possible_names;
+}
+
+/// Add toolchain `file_paths` to argv as `-L` arguments
+pub fn addFilePathLibArgs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+ try argv.ensureUnusedCapacity(tc.file_paths.items.len);
+
+ var bytes_needed: usize = 0;
+ for (tc.file_paths.items) |path| {
+ bytes_needed += path.len + 2; // +2 for `-L`
+ }
+ var bytes = try tc.arena.alloc(u8, bytes_needed);
+ var index: usize = 0;
+ for (tc.file_paths.items) |path| {
+ @memcpy(bytes[index..][0..2], "-L");
+ @memcpy(bytes[index + 2 ..][0..path.len], path);
+ argv.appendAssumeCapacity(bytes[index..][0 .. path.len + 2]);
+ index += path.len + 2;
+ }
+}
+
+/// Search for an executable called `name` or `{triple}-{name} in program_paths and the $PATH environment variable
+/// If not found there, just use `name`
+/// Writes the result to `buf` and returns a slice of it
+fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8 {
+ var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+
+ var tool_specific_name: TargetSpecificToolName = .{};
+ const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_name);
+
+ for (possible_names.constSlice()) |tool_name| {
+ for (tc.program_paths.items) |program_path| {
+ defer fib.reset();
+
+ const candidate = std.fs.path.join(fib.allocator(), &.{ program_path, tool_name }) catch continue;
+
+ if (tc.filesystem.canExecute(candidate) and candidate.len <= buf.len) {
+ @memcpy(buf[0..candidate.len], candidate);
+ return buf[0..candidate.len];
+ }
+ }
+ return tc.filesystem.findProgramByName(tc.driver.comp.gpa, name, tc.driver.comp.environment.path, buf) orelse continue;
+ }
+ @memcpy(buf[0..name.len], name);
+ return buf[0..name.len];
+}
+
+pub fn getSysroot(tc: *const Toolchain) []const u8 {
+ return tc.driver.sysroot orelse system_defaults.sysroot;
+}
+
+/// Search for `name` in a variety of places
+/// TODO: cache results based on `name` so we're not repeatedly allocating the same strings?
+pub fn getFilePath(tc: *const Toolchain, name: []const u8) ![]const u8 {
+ var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+ const allocator = fib.allocator();
+
+ const sysroot = tc.getSysroot();
+
+ // todo check resource dir
+ // todo check compiler RT path
+ const aro_dir = std.fs.path.dirname(tc.driver.aro_name) orelse "";
+ const candidate = try std.fs.path.join(allocator, &.{ aro_dir, "..", name });
+ if (tc.filesystem.exists(candidate)) {
+ return tc.arena.dupe(u8, candidate);
+ }
+
+ if (tc.searchPaths(&fib, sysroot, tc.library_paths.items, name)) |path| {
+ return tc.arena.dupe(u8, path);
+ }
+
+ if (tc.searchPaths(&fib, sysroot, tc.file_paths.items, name)) |path| {
+ return try tc.arena.dupe(u8, path);
+ }
+
+ return name;
+}
+
+/// Search a list of `path_prefixes` for the existence `name`
+/// Assumes that `fba` is a fixed-buffer allocator, so does not free joined path candidates
+fn searchPaths(tc: *const Toolchain, fib: *std.heap.FixedBufferAllocator, sysroot: []const u8, path_prefixes: []const []const u8, name: []const u8) ?[]const u8 {
+ for (path_prefixes) |path| {
+ fib.reset();
+ if (path.len == 0) continue;
+
+ const candidate = if (path[0] == '=')
+ std.fs.path.join(fib.allocator(), &.{ sysroot, path[1..], name }) catch continue
+ else
+ std.fs.path.join(fib.allocator(), &.{ path, name }) catch continue;
+
+ if (tc.filesystem.exists(candidate)) {
+ return candidate;
+ }
+ }
+ return null;
+}
+
+const PathKind = enum {
+ library,
+ file,
+ program,
+};
+
+/// Join `components` into a path. If the path exists, dupe it into the toolchain arena and
+/// add it to the specified path list.
+pub fn addPathIfExists(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
+ var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+
+ const candidate = try std.fs.path.join(fib.allocator(), components);
+
+ if (tc.filesystem.exists(candidate)) {
+ const duped = try tc.arena.dupe(u8, candidate);
+ const dest = switch (dest_kind) {
+ .library => &tc.library_paths,
+ .file => &tc.file_paths,
+ .program => &tc.program_paths,
+ };
+ try dest.append(tc.driver.comp.gpa, duped);
+ }
+}
+
+/// Join `components` using the toolchain arena and add the resulting path to `dest_kind`. Does not check
+/// whether the path actually exists
+pub fn addPathFromComponents(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
+ const full_path = try std.fs.path.join(tc.arena, components);
+ const dest = switch (dest_kind) {
+ .library => &tc.library_paths,
+ .file => &tc.file_paths,
+ .program => &tc.program_paths,
+ };
+ try dest.append(tc.driver.comp.gpa, full_path);
+}
+
+/// Add linker args to `argv`. Does not add path to linker executable as first item; that must be handled separately
+/// Items added to `argv` will be string literals or owned by `tc.arena` so they must not be individually freed
+pub fn buildLinkerArgs(tc: *Toolchain, argv: *std.ArrayList([]const u8)) !void {
+ return switch (tc.inner) {
+ .uninitialized => unreachable,
+ .linux => |*linux| linux.buildLinkerArgs(tc, argv),
+ .unknown => @panic("This toolchain does not support linking yet"),
+ };
+}
+
+fn getDefaultRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
+ if (tc.getTarget().isAndroid()) {
+ return .compiler_rt;
+ }
+ return .libgcc;
+}
+
+pub fn getRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
+ const libname = tc.driver.rtlib orelse system_defaults.rtlib;
+ if (mem.eql(u8, libname, "compiler-rt"))
+ return .compiler_rt
+ else if (mem.eql(u8, libname, "libgcc"))
+ return .libgcc
+ else
+ return tc.getDefaultRuntimeLibKind();
+}
+
+/// TODO
+pub fn getCompilerRt(tc: *const Toolchain, component: []const u8, file_kind: FileKind) ![]const u8 {
+ _ = file_kind;
+ _ = component;
+ _ = tc;
+ return "";
+}
+
+fn getLibGCCKind(tc: *const Toolchain) LibGCCKind {
+ const target = tc.getTarget();
+ if (tc.driver.static_libgcc or tc.driver.static or tc.driver.static_pie or target.isAndroid()) {
+ return .static;
+ }
+ if (tc.driver.shared_libgcc) {
+ return .shared;
+ }
+ return .unspecified;
+}
+
+fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
+ const libname = tc.driver.unwindlib orelse system_defaults.unwindlib;
+ if (libname.len == 0 or mem.eql(u8, libname, "platform")) {
+ switch (tc.getRuntimeLibKind()) {
+ .compiler_rt => {
+ const target = tc.getTarget();
+ if (target.isAndroid() or target.os.tag == .aix) {
+ return .compiler_rt;
+ } else {
+ return .none;
+ }
+ },
+ .libgcc => return .libgcc,
+ }
+ } else if (mem.eql(u8, libname, "none")) {
+ return .none;
+ } else if (mem.eql(u8, libname, "libgcc")) {
+ return .libgcc;
+ } else if (mem.eql(u8, libname, "libunwind")) {
+ if (tc.getRuntimeLibKind() == .libgcc) {
+ try tc.driver.comp.diag.add(.{ .tag = .incompatible_unwindlib }, &.{});
+ }
+ return .compiler_rt;
+ } else {
+ unreachable;
+ }
+}
+
+fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 {
+ if (is_solaris) {
+ return if (needed) "-zignore" else "-zrecord";
+ } else {
+ return if (needed) "--as-needed" else "--no-as-needed";
+ }
+}
+
+fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+ const unw = try tc.getUnwindLibKind();
+ const target = tc.getTarget();
+ if ((target.isAndroid() and unw == .libgcc) or
+ target.os.tag == .elfiamcu or
+ target.ofmt == .wasm or
+ target_util.isWindowsMSVCEnvironment(target) or
+ unw == .none) return;
+
+ const lgk = tc.getLibGCCKind();
+ const as_needed = lgk == .unspecified and !target.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
+ if (as_needed) {
+ try argv.append(getAsNeededOption(target.os.tag == .solaris, true));
+ }
+ switch (unw) {
+ .none => return,
+ .libgcc => if (lgk == .static) try argv.append("-lgcc_eh") else try argv.append("-lgcc_s"),
+ .compiler_rt => if (target.os.tag == .aix) {
+ if (lgk != .static) {
+ try argv.append("-lunwind");
+ }
+ } else if (lgk == .static) {
+ try argv.append("-l:libunwind.a");
+ } else if (lgk == .shared) {
+ if (target_util.isCygwinMinGW(target)) {
+ try argv.append("-l:libunwind.dll.a");
+ } else {
+ try argv.append("-l:libunwind.so");
+ }
+ } else {
+ try argv.append("-lunwind");
+ },
+ }
+
+ if (as_needed) {
+ try argv.append(getAsNeededOption(target.os.tag == .solaris, false));
+ }
+}
+
+fn addLibGCC(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+ const libgcc_kind = tc.getLibGCCKind();
+ if (libgcc_kind == .static or libgcc_kind == .unspecified) {
+ try argv.append("-lgcc");
+ }
+ try tc.addUnwindLibrary(argv);
+ if (libgcc_kind == .shared) {
+ try argv.append("-lgcc");
+ }
+}
+
+pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+ const target = tc.getTarget();
+ const rlt = tc.getRuntimeLibKind();
+ switch (rlt) {
+ .compiler_rt => {
+ // TODO
+ },
+ .libgcc => {
+ if (target_util.isKnownWindowsMSVCEnvironment(target)) {
+ const rtlib_str = tc.driver.rtlib orelse system_defaults.rtlib;
+ if (!mem.eql(u8, rtlib_str, "platform")) {
+ try tc.driver.comp.diag.add(.{ .tag = .unsupported_rtlib_gcc, .extra = .{ .str = "MSVC" } }, &.{});
+ }
+ } else {
+ try tc.addLibGCC(argv);
+ }
+ },
+ }
+
+ if (target.isAndroid() and !tc.driver.static and !tc.driver.static_pie) {
+ try argv.append("-ldl");
+ }
+}
deps/aro/Tree.zig
@@ -0,0 +1,1312 @@
+const std = @import("std");
+const Type = @import("Type.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const Compilation = @import("Compilation.zig");
+const Source = @import("Source.zig");
+const Attribute = @import("Attribute.zig");
+const Value = @import("Value.zig");
+const StringInterner = @import("StringInterner.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+
+const Tree = @This();
+
+pub const Token = struct {
+ id: Id,
+ flags: packed struct {
+ expansion_disabled: bool = false,
+ is_macro_arg: bool = false,
+ } = .{},
+ /// This location contains the actual token slice which might be generated.
+ /// If it is generated then there is guaranteed to be at least one
+ /// expansion location.
+ loc: Source.Location,
+ expansion_locs: ?[*]Source.Location = null,
+
+ pub fn expansionSlice(tok: Token) []const Source.Location {
+ const locs = tok.expansion_locs orelse return &[0]Source.Location{};
+ var i: usize = 0;
+ while (locs[i].id != .unused) : (i += 1) {}
+ return locs[0..i];
+ }
+
+ pub fn addExpansionLocation(tok: *Token, gpa: std.mem.Allocator, new: []const Source.Location) !void {
+ if (new.len == 0 or tok.id == .whitespace) return;
+ var list = std.ArrayList(Source.Location).init(gpa);
+ defer {
+ @memset(list.items.ptr[list.items.len..list.capacity], .{});
+ // Add a sentinel to indicate the end of the list since
+ // the ArrayList's capacity isn't guaranteed to be exactly
+ // what we ask for.
+ if (list.capacity > 0) {
+ list.items.ptr[list.capacity - 1].byte_offset = 1;
+ }
+ tok.expansion_locs = list.items.ptr;
+ }
+
+ if (tok.expansion_locs) |locs| {
+ var i: usize = 0;
+ while (locs[i].id != .unused) : (i += 1) {}
+ list.items = locs[0..i];
+ while (locs[i].byte_offset != 1) : (i += 1) {}
+ list.capacity = i + 1;
+ }
+
+ const min_len = @max(list.items.len + new.len + 1, 4);
+ const wanted_len = std.math.ceilPowerOfTwo(usize, min_len) catch
+ return error.OutOfMemory;
+ try list.ensureTotalCapacity(wanted_len);
+
+ for (new) |new_loc| {
+ if (new_loc.id == .generated) continue;
+ list.appendAssumeCapacity(new_loc);
+ }
+ }
+
+ pub fn free(expansion_locs: ?[*]Source.Location, gpa: std.mem.Allocator) void {
+ const locs = expansion_locs orelse return;
+ var i: usize = 0;
+ while (locs[i].id != .unused) : (i += 1) {}
+ while (locs[i].byte_offset != 1) : (i += 1) {}
+ gpa.free(locs[0 .. i + 1]);
+ }
+
+ pub fn dupe(tok: Token, gpa: std.mem.Allocator) !Token {
+ var copy = tok;
+ copy.expansion_locs = null;
+ try copy.addExpansionLocation(gpa, tok.expansionSlice());
+ return copy;
+ }
+
+ pub const List = std.MultiArrayList(Token);
+ pub const Id = Tokenizer.Token.Id;
+};
+
+pub const TokenIndex = u32;
+pub const NodeIndex = enum(u32) { none, _ };
+pub const ValueMap = std.AutoHashMap(NodeIndex, Value);
+
+comp: *Compilation,
+arena: std.heap.ArenaAllocator,
+generated: []const u8,
+tokens: Token.List.Slice,
+nodes: Node.List.Slice,
+data: []const NodeIndex,
+root_decls: []const NodeIndex,
+strings: []const u8,
+value_map: ValueMap,
+
+pub fn deinit(tree: *Tree) void {
+ tree.comp.gpa.free(tree.root_decls);
+ tree.comp.gpa.free(tree.data);
+ tree.comp.gpa.free(tree.strings);
+ tree.nodes.deinit(tree.comp.gpa);
+ tree.arena.deinit();
+ tree.value_map.deinit();
+}
+
+pub const GNUAssemblyQualifiers = struct {
+ @"volatile": bool = false,
+ @"inline": bool = false,
+ goto: bool = false,
+};
+
+pub const Node = struct {
+ tag: Tag,
+ ty: Type = .{ .specifier = .void },
+ data: Data,
+
+ pub const Range = struct { start: u32, end: u32 };
+
+ pub const Data = union {
+ decl: struct {
+ name: TokenIndex,
+ node: NodeIndex = .none,
+ },
+ decl_ref: TokenIndex,
+ range: Range,
+ if3: struct {
+ cond: NodeIndex,
+ body: u32,
+ },
+ un: NodeIndex,
+ bin: struct {
+ lhs: NodeIndex,
+ rhs: NodeIndex,
+ },
+ member: struct {
+ lhs: NodeIndex,
+ index: u32,
+ },
+ union_init: struct {
+ field_index: u32,
+ node: NodeIndex,
+ },
+ cast: struct {
+ operand: NodeIndex,
+ kind: CastKind,
+ },
+ int: u64,
+ return_zero: bool,
+
+ pub fn forDecl(data: Data, tree: Tree) struct {
+ decls: []const NodeIndex,
+ cond: NodeIndex,
+ incr: NodeIndex,
+ body: NodeIndex,
+ } {
+ const items = tree.data[data.range.start..data.range.end];
+ const decls = items[0 .. items.len - 3];
+
+ return .{
+ .decls = decls,
+ .cond = items[items.len - 3],
+ .incr = items[items.len - 2],
+ .body = items[items.len - 1],
+ };
+ }
+
+ pub fn forStmt(data: Data, tree: Tree) struct {
+ init: NodeIndex,
+ cond: NodeIndex,
+ incr: NodeIndex,
+ body: NodeIndex,
+ } {
+ const items = tree.data[data.if3.body..];
+
+ return .{
+ .init = items[0],
+ .cond = items[1],
+ .incr = items[2],
+ .body = data.if3.cond,
+ };
+ }
+ };
+
+ pub const List = std.MultiArrayList(Node);
+};
+
+pub const CastKind = enum(u8) {
+ /// Does nothing except possibly add qualifiers
+ no_op,
+ /// Interpret one bit pattern as another. Used for operands which have the same
+ /// size and unrelated types, e.g. casting one pointer type to another
+ bitcast,
+ /// Convert T[] to T *
+ array_to_pointer,
+ /// Converts an lvalue to an rvalue
+ lval_to_rval,
+ /// Convert a function type to a pointer to a function
+ function_to_pointer,
+ /// Convert a pointer type to a _Bool
+ pointer_to_bool,
+ /// Convert a pointer type to an integer type
+ pointer_to_int,
+ /// Convert _Bool to an integer type
+ bool_to_int,
+ /// Convert _Bool to a floating type
+ bool_to_float,
+ /// Convert a _Bool to a pointer; will cause a warning
+ bool_to_pointer,
+ /// Convert an integer type to _Bool
+ int_to_bool,
+ /// Convert an integer to a floating type
+ int_to_float,
+ /// Convert a complex integer to a complex floating type
+ complex_int_to_complex_float,
+ /// Convert an integer type to a pointer type
+ int_to_pointer,
+ /// Convert a floating type to a _Bool
+ float_to_bool,
+ /// Convert a floating type to an integer
+ float_to_int,
+ /// Convert a complex floating type to a complex integer
+ complex_float_to_complex_int,
+ /// Convert one integer type to another
+ int_cast,
+ /// Convert one complex integer type to another
+ complex_int_cast,
+ /// Convert real part of complex integer to a integer
+ complex_int_to_real,
+ /// Create a complex integer type using operand as the real part
+ real_to_complex_int,
+ /// Convert one floating type to another
+ float_cast,
+ /// Convert one complex floating type to another
+ complex_float_cast,
+ /// Convert real part of complex float to a float
+ complex_float_to_real,
+ /// Create a complex floating type using operand as the real part
+ real_to_complex_float,
+ /// Convert type to void
+ to_void,
+ /// Convert a literal 0 to a null pointer
+ null_to_pointer,
+ /// GNU cast-to-union extension
+ union_cast,
+ /// Create vector where each value is same as the input scalar.
+ vector_splat,
+};
+
+pub const Tag = enum(u8) {
+ /// Must appear at index 0. Also used as the tag for __builtin_types_compatible_p arguments, since the arguments are types
+ /// Reaching it is always the result of a bug.
+ invalid,
+
+ // ====== Decl ======
+
+ // _Static_assert
+ static_assert,
+
+ // function prototype
+ fn_proto,
+ static_fn_proto,
+ inline_fn_proto,
+ inline_static_fn_proto,
+
+ // function definition
+ fn_def,
+ static_fn_def,
+ inline_fn_def,
+ inline_static_fn_def,
+
+ // variable declaration
+ @"var",
+ extern_var,
+ static_var,
+ // same as static_var, used for __func__, __FUNCTION__ and __PRETTY_FUNCTION__
+ implicit_static_var,
+ threadlocal_var,
+ threadlocal_extern_var,
+ threadlocal_static_var,
+
+ /// __asm__("...") at file scope
+ file_scope_asm,
+
+ // typedef declaration
+ typedef,
+
+ // container declarations
+ /// { lhs; rhs; }
+ struct_decl_two,
+ /// { lhs; rhs; }
+ union_decl_two,
+ /// { lhs, rhs, }
+ enum_decl_two,
+ /// { range }
+ struct_decl,
+ /// { range }
+ union_decl,
+ /// { range }
+ enum_decl,
+ /// struct decl_ref;
+ struct_forward_decl,
+ /// union decl_ref;
+ union_forward_decl,
+ /// enum decl_ref;
+ enum_forward_decl,
+
+ /// name = node
+ enum_field_decl,
+ /// ty name : node
+ /// name == 0 means unnamed
+ record_field_decl,
+ /// Used when a record has an unnamed record as a field
+ indirect_record_field_decl,
+
+ // ====== Stmt ======
+
+ labeled_stmt,
+ /// { first; second; } first and second may be null
+ compound_stmt_two,
+ /// { data }
+ compound_stmt,
+ /// if (first) data[second] else data[second+1];
+ if_then_else_stmt,
+ /// if (first) second; second may be null
+ if_then_stmt,
+ /// switch (first) second
+ switch_stmt,
+ /// case first: second
+ case_stmt,
+ /// case data[body]...data[body+1]: cond
+ case_range_stmt,
+ /// default: first
+ default_stmt,
+ /// while (first) second
+ while_stmt,
+ /// do second while(first);
+ do_while_stmt,
+ /// for (data[..]; data[len-3]; data[len-2]) data[len-1]
+ for_decl_stmt,
+ /// for (;;;) first
+ forever_stmt,
+ /// for (data[first]; data[first+1]; data[first+2]) second
+ for_stmt,
+ /// goto first;
+ goto_stmt,
+ /// goto *un;
+ computed_goto_stmt,
+ // continue; first and second unused
+ continue_stmt,
+ // break; first and second unused
+ break_stmt,
+ // null statement (just a semicolon); first and second unused
+ null_stmt,
+ /// return first; first may be null
+ return_stmt,
+ /// Assembly statement of the form __asm__("string literal")
+ gnu_asm_simple,
+
+ // ====== Expr ======
+
+ /// lhs , rhs
+ comma_expr,
+ /// lhs ? data[0] : data[1]
+ binary_cond_expr,
+ /// Used as the base for casts of the lhs in `binary_cond_expr`.
+ cond_dummy_expr,
+ /// lhs ? data[0] : data[1]
+ cond_expr,
+ /// lhs = rhs
+ assign_expr,
+ /// lhs *= rhs
+ mul_assign_expr,
+ /// lhs /= rhs
+ div_assign_expr,
+ /// lhs %= rhs
+ mod_assign_expr,
+ /// lhs += rhs
+ add_assign_expr,
+ /// lhs -= rhs
+ sub_assign_expr,
+ /// lhs <<= rhs
+ shl_assign_expr,
+ /// lhs >>= rhs
+ shr_assign_expr,
+ /// lhs &= rhs
+ bit_and_assign_expr,
+ /// lhs ^= rhs
+ bit_xor_assign_expr,
+ /// lhs |= rhs
+ bit_or_assign_expr,
+ /// lhs || rhs
+ bool_or_expr,
+ /// lhs && rhs
+ bool_and_expr,
+ /// lhs | rhs
+ bit_or_expr,
+ /// lhs ^ rhs
+ bit_xor_expr,
+ /// lhs & rhs
+ bit_and_expr,
+ /// lhs == rhs
+ equal_expr,
+ /// lhs != rhs
+ not_equal_expr,
+ /// lhs < rhs
+ less_than_expr,
+ /// lhs <= rhs
+ less_than_equal_expr,
+ /// lhs > rhs
+ greater_than_expr,
+ /// lhs >= rhs
+ greater_than_equal_expr,
+ /// lhs << rhs
+ shl_expr,
+ /// lhs >> rhs
+ shr_expr,
+ /// lhs + rhs
+ add_expr,
+ /// lhs - rhs
+ sub_expr,
+ /// lhs * rhs
+ mul_expr,
+ /// lhs / rhs
+ div_expr,
+ /// lhs % rhs
+ mod_expr,
+ /// Explicit: (type) cast
+ explicit_cast,
+ /// Implicit: cast
+ implicit_cast,
+ /// &un
+ addr_of_expr,
+ /// &&decl_ref
+ addr_of_label,
+ /// *un
+ deref_expr,
+ /// +un
+ plus_expr,
+ /// -un
+ negate_expr,
+ /// ~un
+ bit_not_expr,
+ /// !un
+ bool_not_expr,
+ /// ++un
+ pre_inc_expr,
+ /// --un
+ pre_dec_expr,
+ /// __imag un
+ imag_expr,
+ /// __real un
+ real_expr,
+ /// lhs[rhs] lhs is pointer/array type, rhs is integer type
+ array_access_expr,
+ /// first(second) second may be 0
+ call_expr_one,
+ /// data[0](data[1..])
+ call_expr,
+ /// decl
+ builtin_call_expr_one,
+ builtin_call_expr,
+ /// lhs.member
+ member_access_expr,
+ /// lhs->member
+ member_access_ptr_expr,
+ /// un++
+ post_inc_expr,
+ /// un--
+ post_dec_expr,
+ /// (un)
+ paren_expr,
+ /// decl_ref
+ decl_ref_expr,
+ /// decl_ref
+ enumeration_ref,
+ /// C23 bool literal `true` / `false`
+ bool_literal,
+ /// C23 nullptr literal
+ nullptr_literal,
+ /// integer literal, always unsigned
+ int_literal,
+ /// Same as int_literal, but originates from a char literal
+ char_literal,
+ /// _Float16 literal
+ float16_literal,
+ /// f32 literal
+ float_literal,
+ /// f64 literal
+ double_literal,
+ /// wraps a float or double literal: un
+ imaginary_literal,
+ /// tree.str[index..][0..len]
+ string_literal_expr,
+ /// sizeof(un?)
+ sizeof_expr,
+ /// _Alignof(un?)
+ alignof_expr,
+ /// _Generic(controlling lhs, chosen rhs)
+ generic_expr_one,
+ /// _Generic(controlling range[0], chosen range[1], rest range[2..])
+ generic_expr,
+ /// ty: un
+ generic_association_expr,
+ // default: un
+ generic_default_expr,
+ /// __builtin_choose_expr(lhs, data[0], data[1])
+ builtin_choose_expr,
+ /// __builtin_types_compatible_p(lhs, rhs)
+ builtin_types_compatible_p,
+ /// decl - special builtins require custom parsing
+ special_builtin_call_one,
+ /// ({ un })
+ stmt_expr,
+
+ // ====== Initializer expressions ======
+
+ /// { lhs, rhs }
+ array_init_expr_two,
+ /// { range }
+ array_init_expr,
+ /// { lhs, rhs }
+ struct_init_expr_two,
+ /// { range }
+ struct_init_expr,
+ /// { union_init }
+ union_init_expr,
+ /// (ty){ un }
+ compound_literal_expr,
+
+ /// Inserted at the end of a function body if no return stmt is found.
+ /// ty is the functions return type
+ /// data is return_zero which is true if the function is called "main" and ty is compatible with int
+ implicit_return,
+
+ /// Inserted in array_init_expr to represent unspecified elements.
+ /// data.int contains the amount of elements.
+ array_filler_expr,
+ /// Inserted in record and scalar initializers for unspecified elements.
+ default_init_expr,
+
+ pub fn isImplicit(tag: Tag) bool {
+ return switch (tag) {
+ .implicit_cast,
+ .implicit_return,
+ .array_filler_expr,
+ .default_init_expr,
+ .implicit_static_var,
+ .cond_dummy_expr,
+ => true,
+ else => false,
+ };
+ }
+};
+
+pub fn isBitfield(nodes: Node.List.Slice, node: NodeIndex) bool {
+ return bitfieldWidth(nodes, node, false) != null;
+}
+
+/// Returns null if node is not a bitfield. If inspect_lval is true, this function will
+/// recurse into implicit lval_to_rval casts (useful for arithmetic conversions)
+pub fn bitfieldWidth(nodes: Node.List.Slice, node: NodeIndex, inspect_lval: bool) ?u32 {
+ if (node == .none) return null;
+ switch (nodes.items(.tag)[@intFromEnum(node)]) {
+ .member_access_expr, .member_access_ptr_expr => {
+ const member = nodes.items(.data)[@intFromEnum(node)].member;
+ var ty = nodes.items(.ty)[@intFromEnum(member.lhs)];
+ if (ty.isPtr()) ty = ty.elemType();
+ const record_ty = ty.get(.@"struct") orelse ty.get(.@"union") orelse return null;
+ const field = record_ty.data.record.fields[member.index];
+ return field.bit_width;
+ },
+ .implicit_cast => {
+ if (!inspect_lval) return null;
+
+ const data = nodes.items(.data)[@intFromEnum(node)];
+ return switch (data.cast.kind) {
+ .lval_to_rval => bitfieldWidth(nodes, data.cast.operand, false),
+ else => null,
+ };
+ },
+ else => return null,
+ }
+}
+
+pub fn isLval(nodes: Node.List.Slice, extra: []const NodeIndex, value_map: ValueMap, node: NodeIndex) bool {
+ var is_const: bool = undefined;
+ return isLvalExtra(nodes, extra, value_map, node, &is_const);
+}
+
+pub fn isLvalExtra(nodes: Node.List.Slice, extra: []const NodeIndex, value_map: ValueMap, node: NodeIndex, is_const: *bool) bool {
+ is_const.* = false;
+ switch (nodes.items(.tag)[@intFromEnum(node)]) {
+ .compound_literal_expr => {
+ is_const.* = nodes.items(.ty)[@intFromEnum(node)].isConst();
+ return true;
+ },
+ .string_literal_expr => return true,
+ .member_access_ptr_expr => {
+ const lhs_expr = nodes.items(.data)[@intFromEnum(node)].member.lhs;
+ const ptr_ty = nodes.items(.ty)[@intFromEnum(lhs_expr)];
+ if (ptr_ty.isPtr()) is_const.* = ptr_ty.elemType().isConst();
+ return true;
+ },
+ .array_access_expr => {
+ const lhs_expr = nodes.items(.data)[@intFromEnum(node)].bin.lhs;
+ if (lhs_expr != .none) {
+ const array_ty = nodes.items(.ty)[@intFromEnum(lhs_expr)];
+ if (array_ty.isPtr() or array_ty.isArray()) is_const.* = array_ty.elemType().isConst();
+ }
+ return true;
+ },
+ .decl_ref_expr => {
+ const decl_ty = nodes.items(.ty)[@intFromEnum(node)];
+ is_const.* = decl_ty.isConst();
+ return true;
+ },
+ .deref_expr => {
+ const data = nodes.items(.data)[@intFromEnum(node)];
+ const operand_ty = nodes.items(.ty)[@intFromEnum(data.un)];
+ if (operand_ty.isFunc()) return false;
+ if (operand_ty.isPtr() or operand_ty.isArray()) is_const.* = operand_ty.elemType().isConst();
+ return true;
+ },
+ .member_access_expr => {
+ const data = nodes.items(.data)[@intFromEnum(node)];
+ return isLvalExtra(nodes, extra, value_map, data.member.lhs, is_const);
+ },
+ .paren_expr => {
+ const data = nodes.items(.data)[@intFromEnum(node)];
+ return isLvalExtra(nodes, extra, value_map, data.un, is_const);
+ },
+ .builtin_choose_expr => {
+ const data = nodes.items(.data)[@intFromEnum(node)];
+
+ if (value_map.get(data.if3.cond)) |val| {
+ const offset = @intFromBool(val.isZero());
+ return isLvalExtra(nodes, extra, value_map, extra[data.if3.body + offset], is_const);
+ }
+ return false;
+ },
+ else => return false,
+ }
+}
+
+pub fn dumpStr(retained_strings: []const u8, range: Value.ByteRange, tag: Tag, writer: anytype) !void {
+ switch (tag) {
+ .string_literal_expr => {
+ const lit_range = range.trim(1); // remove null-terminator
+ const str = lit_range.slice(retained_strings);
+ try writer.print("\"{}\"", .{std.zig.fmtEscapes(str)});
+ },
+ else => unreachable,
+ }
+}
+
+pub fn tokSlice(tree: Tree, tok_i: TokenIndex) []const u8 {
+ if (tree.tokens.items(.id)[tok_i].lexeme()) |some| return some;
+ const loc = tree.tokens.items(.loc)[tok_i];
+ var tmp_tokenizer = Tokenizer{
+ .buf = tree.comp.getSource(loc.id).buf,
+ .comp = tree.comp,
+ .index = loc.byte_offset,
+ .source = .generated,
+ };
+ const tok = tmp_tokenizer.next();
+ return tmp_tokenizer.buf[tok.start..tok.end];
+}
+
+pub fn dump(tree: Tree, color: bool, writer: anytype) @TypeOf(writer).Error!void {
+ const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper();
+ defer mapper.deinit(tree.comp.gpa);
+
+ for (tree.root_decls) |i| {
+ try tree.dumpNode(i, 0, mapper, color, writer);
+ try writer.writeByte('\n');
+ }
+}
+
+fn dumpFieldAttributes(attributes: []const Attribute, level: u32, strings: []const u8, writer: anytype) !void {
+ for (attributes) |attr| {
+ try writer.writeByteNTimes(' ', level);
+ try writer.print("field attr: {s}", .{@tagName(attr.tag)});
+ try dumpAttribute(attr, strings, writer);
+ }
+}
+
+fn dumpAttribute(attr: Attribute, strings: []const u8, writer: anytype) !void {
+ switch (attr.tag) {
+ inline else => |tag| {
+ const args = @field(attr.args, @tagName(tag));
+ if (@TypeOf(args) == void) {
+ try writer.writeByte('\n');
+ return;
+ }
+ try writer.writeByte(' ');
+ inline for (@typeInfo(@TypeOf(args)).Struct.fields, 0..) |f, i| {
+ if (comptime std.mem.eql(u8, f.name, "__name_tok")) continue;
+ if (i != 0) {
+ try writer.writeAll(", ");
+ }
+ try writer.writeAll(f.name);
+ try writer.writeAll(": ");
+ switch (f.type) {
+ Value.ByteRange => try writer.print("\"{s}\"", .{@field(args, f.name).slice(strings)}),
+ ?Value.ByteRange => try writer.print("\"{?s}\"", .{if (@field(args, f.name)) |range| range.slice(strings) else null}),
+ else => switch (@typeInfo(f.type)) {
+ .Enum => try writer.writeAll(@tagName(@field(args, f.name))),
+ else => try writer.print("{any}", .{@field(args, f.name)}),
+ },
+ }
+ }
+ try writer.writeByte('\n');
+ return;
+ },
+ }
+}
+
+fn dumpNode(tree: Tree, node: NodeIndex, level: u32, mapper: StringInterner.TypeMapper, color: bool, w: anytype) @TypeOf(w).Error!void {
+ const delta = 2;
+ const half = delta / 2;
+ const util = @import("util.zig");
+ const TYPE = util.Color.purple;
+ const TAG = util.Color.cyan;
+ const IMPLICIT = util.Color.blue;
+ const NAME = util.Color.red;
+ const LITERAL = util.Color.green;
+ const ATTRIBUTE = util.Color.yellow;
+ std.debug.assert(node != .none);
+
+ const tag = tree.nodes.items(.tag)[@intFromEnum(node)];
+ const data = tree.nodes.items(.data)[@intFromEnum(node)];
+ const ty = tree.nodes.items(.ty)[@intFromEnum(node)];
+ try w.writeByteNTimes(' ', level);
+
+ if (color) util.setColor(if (tag.isImplicit()) IMPLICIT else TAG, w);
+ try w.print("{s}: ", .{@tagName(tag)});
+ if (tag == .implicit_cast or tag == .explicit_cast) {
+ if (color) util.setColor(.white, w);
+ try w.print("({s}) ", .{@tagName(data.cast.kind)});
+ }
+ if (color) util.setColor(TYPE, w);
+ try w.writeByte('\'');
+ try ty.dump(mapper, tree.comp.langopts, w);
+ try w.writeByte('\'');
+
+ if (isLval(tree.nodes, tree.data, tree.value_map, node)) {
+ if (color) util.setColor(ATTRIBUTE, w);
+ try w.writeAll(" lvalue");
+ }
+ if (isBitfield(tree.nodes, node)) {
+ if (color) util.setColor(ATTRIBUTE, w);
+ try w.writeAll(" bitfield");
+ }
+ if (tree.value_map.get(node)) |val| {
+ if (color) util.setColor(LITERAL, w);
+ try w.writeAll(" (value: ");
+ try val.dump(ty, tree.comp, tree.strings, w);
+ try w.writeByte(')');
+ }
+ if (tag == .implicit_return and data.return_zero) {
+ if (color) util.setColor(IMPLICIT, w);
+ try w.writeAll(" (value: 0)");
+ if (color) util.setColor(.reset, w);
+ }
+
+ try w.writeAll("\n");
+ if (color) util.setColor(.reset, w);
+
+ if (ty.specifier == .attributed) {
+ if (color) util.setColor(ATTRIBUTE, w);
+ for (ty.data.attributed.attributes) |attr| {
+ try w.writeByteNTimes(' ', level + half);
+ try w.print("attr: {s}", .{@tagName(attr.tag)});
+ try dumpAttribute(attr, tree.strings, w);
+ }
+ if (color) util.setColor(.reset, w);
+ }
+
+ switch (tag) {
+ .invalid => unreachable,
+ .file_scope_asm => {
+ try w.writeByteNTimes(' ', level + 1);
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ },
+ .gnu_asm_simple => {
+ try w.writeByteNTimes(' ', level);
+ try tree.dumpNode(data.un, level, mapper, color, w);
+ },
+ .static_assert => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("condition:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+ if (data.bin.rhs != .none) {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("diagnostic:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ }
+ },
+ .fn_proto,
+ .static_fn_proto,
+ .inline_fn_proto,
+ .inline_static_fn_proto,
+ => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ },
+ .fn_def,
+ .static_fn_def,
+ .inline_fn_def,
+ .inline_static_fn_def,
+ => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("body:\n");
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ },
+ .typedef,
+ .@"var",
+ .extern_var,
+ .static_var,
+ .implicit_static_var,
+ .threadlocal_var,
+ .threadlocal_extern_var,
+ .threadlocal_static_var,
+ => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ if (data.decl.node != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("init:\n");
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ }
+ },
+ .enum_field_decl => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ if (data.decl.node != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("value:\n");
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ }
+ },
+ .record_field_decl => {
+ if (data.decl.name != 0) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ }
+ if (data.decl.node != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("bits:\n");
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ }
+ },
+ .indirect_record_field_decl => {},
+ .compound_stmt,
+ .array_init_expr,
+ .struct_init_expr,
+ .enum_decl,
+ .struct_decl,
+ .union_decl,
+ => {
+ const maybe_field_attributes = if (ty.getRecord()) |record| record.field_attributes else null;
+ for (tree.data[data.range.start..data.range.end], 0..) |stmt, i| {
+ if (i != 0) try w.writeByte('\n');
+ try tree.dumpNode(stmt, level + delta, mapper, color, w);
+ if (maybe_field_attributes) |field_attributes| {
+ if (field_attributes[i].len == 0) continue;
+
+ if (color) util.setColor(ATTRIBUTE, w);
+ try dumpFieldAttributes(field_attributes[i], level + delta + half, tree.strings, w);
+ if (color) util.setColor(.reset, w);
+ }
+ }
+ },
+ .compound_stmt_two,
+ .array_init_expr_two,
+ .struct_init_expr_two,
+ .enum_decl_two,
+ .struct_decl_two,
+ .union_decl_two,
+ => {
+ var attr_array = [2][]const Attribute{ &.{}, &.{} };
+ const empty: [][]const Attribute = &attr_array;
+ const field_attributes = if (ty.getRecord()) |record| (record.field_attributes orelse empty.ptr) else empty.ptr;
+ if (data.bin.lhs != .none) {
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+ if (field_attributes[0].len > 0) {
+ if (color) util.setColor(ATTRIBUTE, w);
+ try dumpFieldAttributes(field_attributes[0], level + delta + half, tree.strings, w);
+ if (color) util.setColor(.reset, w);
+ }
+ }
+ if (data.bin.rhs != .none) {
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ if (field_attributes[1].len > 0) {
+ if (color) util.setColor(ATTRIBUTE, w);
+ try dumpFieldAttributes(field_attributes[1], level + delta + half, tree.strings, w);
+ if (color) util.setColor(.reset, w);
+ }
+ }
+ },
+ .union_init_expr => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("field index: ");
+ if (color) util.setColor(LITERAL, w);
+ try w.print("{d}\n", .{data.union_init.field_index});
+ if (color) util.setColor(.reset, w);
+ if (data.union_init.node != .none) {
+ try tree.dumpNode(data.union_init.node, level + delta, mapper, color, w);
+ }
+ },
+ .compound_literal_expr => {
+ try tree.dumpNode(data.un, level + half, mapper, color, w);
+ },
+ .labeled_stmt => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("label: ");
+ if (color) util.setColor(LITERAL, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ if (data.decl.node != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("stmt:\n");
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ }
+ },
+ .case_stmt => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("value:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+ if (data.bin.rhs != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("stmt:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ }
+ },
+ .case_range_stmt => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("range start:\n");
+ try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, color, w);
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("range end:\n");
+ try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, color, w);
+
+ if (data.if3.cond != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("stmt:\n");
+ try tree.dumpNode(data.if3.cond, level + delta, mapper, color, w);
+ }
+ },
+ .default_stmt => {
+ if (data.un != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("stmt:\n");
+ try tree.dumpNode(data.un, level + delta, mapper, color, w);
+ }
+ },
+ .binary_cond_expr, .cond_expr, .if_then_else_stmt, .builtin_choose_expr => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("cond:\n");
+ try tree.dumpNode(data.if3.cond, level + delta, mapper, color, w);
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("then:\n");
+ try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, color, w);
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("else:\n");
+ try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, color, w);
+ },
+ .builtin_types_compatible_p => {
+ std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.lhs)] == .invalid);
+ std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.rhs)] == .invalid);
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("lhs: ");
+
+ const lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.lhs)];
+ if (color) util.setColor(TYPE, w);
+ try lhs_ty.dump(mapper, tree.comp.langopts, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeByte('\n');
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("rhs: ");
+
+ const rhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.rhs)];
+ if (color) util.setColor(TYPE, w);
+ try rhs_ty.dump(mapper, tree.comp.langopts, w);
+ if (color) util.setColor(.reset, w);
+ try w.writeByte('\n');
+ },
+ .if_then_stmt => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("cond:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+
+ if (data.bin.rhs != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("then:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ }
+ },
+ .switch_stmt, .while_stmt, .do_while_stmt => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("cond:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+
+ if (data.bin.rhs != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("body:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ }
+ },
+ .for_decl_stmt => {
+ const for_decl = data.forDecl(tree);
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("decl:\n");
+ for (for_decl.decls) |decl| {
+ try tree.dumpNode(decl, level + delta, mapper, color, w);
+ try w.writeByte('\n');
+ }
+ if (for_decl.cond != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("cond:\n");
+ try tree.dumpNode(for_decl.cond, level + delta, mapper, color, w);
+ }
+ if (for_decl.incr != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("incr:\n");
+ try tree.dumpNode(for_decl.incr, level + delta, mapper, color, w);
+ }
+ if (for_decl.body != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("body:\n");
+ try tree.dumpNode(for_decl.body, level + delta, mapper, color, w);
+ }
+ },
+ .forever_stmt => {
+ if (data.un != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("body:\n");
+ try tree.dumpNode(data.un, level + delta, mapper, color, w);
+ }
+ },
+ .for_stmt => {
+ const for_stmt = data.forStmt(tree);
+
+ if (for_stmt.init != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("init:\n");
+ try tree.dumpNode(for_stmt.init, level + delta, mapper, color, w);
+ }
+ if (for_stmt.cond != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("cond:\n");
+ try tree.dumpNode(for_stmt.cond, level + delta, mapper, color, w);
+ }
+ if (for_stmt.incr != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("incr:\n");
+ try tree.dumpNode(for_stmt.incr, level + delta, mapper, color, w);
+ }
+ if (for_stmt.body != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("body:\n");
+ try tree.dumpNode(for_stmt.body, level + delta, mapper, color, w);
+ }
+ },
+ .goto_stmt, .addr_of_label => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("label: ");
+ if (color) util.setColor(LITERAL, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
+ if (color) util.setColor(.reset, w);
+ },
+ .continue_stmt, .break_stmt, .implicit_return, .null_stmt => {},
+ .return_stmt => {
+ if (data.un != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("expr:\n");
+ try tree.dumpNode(data.un, level + delta, mapper, color, w);
+ }
+ },
+ .call_expr => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("lhs:\n");
+ try tree.dumpNode(tree.data[data.range.start], level + delta, mapper, color, w);
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("args:\n");
+ for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, color, w);
+ },
+ .call_expr_one => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("lhs:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+ if (data.bin.rhs != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("arg:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ }
+ },
+ .builtin_call_expr => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(@intFromEnum(tree.data[data.range.start]))});
+ if (color) util.setColor(.reset, w);
+
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("args:\n");
+ for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, color, w);
+ },
+ .builtin_call_expr_one => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ if (data.decl.node != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("arg:\n");
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ }
+ },
+ .special_builtin_call_one => {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+ if (color) util.setColor(.reset, w);
+ if (data.decl.node != .none) {
+ try w.writeByteNTimes(' ', level + half);
+ try w.writeAll("arg:\n");
+ try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+ }
+ },
+ .comma_expr,
+ .assign_expr,
+ .mul_assign_expr,
+ .div_assign_expr,
+ .mod_assign_expr,
+ .add_assign_expr,
+ .sub_assign_expr,
+ .shl_assign_expr,
+ .shr_assign_expr,
+ .bit_and_assign_expr,
+ .bit_xor_assign_expr,
+ .bit_or_assign_expr,
+ .bool_or_expr,
+ .bool_and_expr,
+ .bit_or_expr,
+ .bit_xor_expr,
+ .bit_and_expr,
+ .equal_expr,
+ .not_equal_expr,
+ .less_than_expr,
+ .less_than_equal_expr,
+ .greater_than_expr,
+ .greater_than_equal_expr,
+ .shl_expr,
+ .shr_expr,
+ .add_expr,
+ .sub_expr,
+ .mul_expr,
+ .div_expr,
+ .mod_expr,
+ => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("lhs:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("rhs:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ },
+ .explicit_cast, .implicit_cast => try tree.dumpNode(data.cast.operand, level + delta, mapper, color, w),
+ .addr_of_expr,
+ .computed_goto_stmt,
+ .deref_expr,
+ .plus_expr,
+ .negate_expr,
+ .bit_not_expr,
+ .bool_not_expr,
+ .pre_inc_expr,
+ .pre_dec_expr,
+ .imag_expr,
+ .real_expr,
+ .post_inc_expr,
+ .post_dec_expr,
+ .paren_expr,
+ => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("operand:\n");
+ try tree.dumpNode(data.un, level + delta, mapper, color, w);
+ },
+ .decl_ref_expr => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
+ if (color) util.setColor(.reset, w);
+ },
+ .enumeration_ref => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
+ if (color) util.setColor(.reset, w);
+ },
+ .bool_literal,
+ .nullptr_literal,
+ .int_literal,
+ .char_literal,
+ .float16_literal,
+ .float_literal,
+ .double_literal,
+ .string_literal_expr,
+ => {},
+ .member_access_expr, .member_access_ptr_expr => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("lhs:\n");
+ try tree.dumpNode(data.member.lhs, level + delta, mapper, color, w);
+
+ var lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
+ if (lhs_ty.isPtr()) lhs_ty = lhs_ty.elemType();
+ lhs_ty = lhs_ty.canonicalize(.standard);
+
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("name: ");
+ if (color) util.setColor(NAME, w);
+ try w.print("{s}\n", .{mapper.lookup(lhs_ty.data.record.fields[data.member.index].name)});
+ if (color) util.setColor(.reset, w);
+ },
+ .array_access_expr => {
+ if (data.bin.lhs != .none) {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("lhs:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+ }
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("index:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ },
+ .sizeof_expr, .alignof_expr => {
+ if (data.un != .none) {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("expr:\n");
+ try tree.dumpNode(data.un, level + delta, mapper, color, w);
+ }
+ },
+ .generic_expr_one => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("controlling:\n");
+ try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+ try w.writeByteNTimes(' ', level + 1);
+ if (data.bin.rhs != .none) {
+ try w.writeAll("chosen:\n");
+ try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+ }
+ },
+ .generic_expr => {
+ const nodes = tree.data[data.range.start..data.range.end];
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("controlling:\n");
+ try tree.dumpNode(nodes[0], level + delta, mapper, color, w);
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("chosen:\n");
+ try tree.dumpNode(nodes[1], level + delta, mapper, color, w);
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("rest:\n");
+ for (nodes[2..]) |expr| {
+ try tree.dumpNode(expr, level + delta, mapper, color, w);
+ }
+ },
+ .generic_association_expr, .generic_default_expr, .stmt_expr, .imaginary_literal => {
+ try tree.dumpNode(data.un, level + delta, mapper, color, w);
+ },
+ .array_filler_expr => {
+ try w.writeByteNTimes(' ', level + 1);
+ try w.writeAll("count: ");
+ if (color) util.setColor(LITERAL, w);
+ try w.print("{d}\n", .{data.int});
+ if (color) util.setColor(.reset, w);
+ },
+ .struct_forward_decl,
+ .union_forward_decl,
+ .enum_forward_decl,
+ .default_init_expr,
+ .cond_dummy_expr,
+ => {},
+ }
+}
deps/aro/Type.zig
@@ -0,0 +1,2692 @@
+const std = @import("std");
+const Tree = @import("Tree.zig");
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Parser = @import("Parser.zig");
+const Compilation = @import("Compilation.zig");
+const Attribute = @import("Attribute.zig");
+const StringInterner = @import("StringInterner.zig");
+const StringId = StringInterner.StringId;
+const target_util = @import("target.zig");
+const LangOpts = @import("LangOpts.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+
+const Type = @This();
+
+pub const Qualifiers = packed struct {
+ @"const": bool = false,
+ atomic: bool = false,
+ @"volatile": bool = false,
+ restrict: bool = false,
+
+ // for function parameters only, stored here since it fits in the padding
+ register: bool = false,
+
+ pub fn any(quals: Qualifiers) bool {
+ return quals.@"const" or quals.restrict or quals.@"volatile" or quals.atomic;
+ }
+
+ pub fn dump(quals: Qualifiers, w: anytype) !void {
+ if (quals.@"const") try w.writeAll("const ");
+ if (quals.atomic) try w.writeAll("_Atomic ");
+ if (quals.@"volatile") try w.writeAll("volatile ");
+ if (quals.restrict) try w.writeAll("restrict ");
+ if (quals.register) try w.writeAll("register ");
+ }
+
+ /// Merge the const/volatile qualifiers, used by type resolution
+ /// of the conditional operator
+ pub fn mergeCV(a: Qualifiers, b: Qualifiers) Qualifiers {
+ return .{
+ .@"const" = a.@"const" or b.@"const",
+ .@"volatile" = a.@"volatile" or b.@"volatile",
+ };
+ }
+
+ /// Merge all qualifiers, used by typeof()
+ fn mergeAll(a: Qualifiers, b: Qualifiers) Qualifiers {
+ return .{
+ .@"const" = a.@"const" or b.@"const",
+ .atomic = a.atomic or b.atomic,
+ .@"volatile" = a.@"volatile" or b.@"volatile",
+ .restrict = a.restrict or b.restrict,
+ .register = a.register or b.register,
+ };
+ }
+
+ /// Checks if a has all the qualifiers of b
+ pub fn hasQuals(a: Qualifiers, b: Qualifiers) bool {
+ if (b.@"const" and !a.@"const") return false;
+ if (b.@"volatile" and !a.@"volatile") return false;
+ if (b.atomic and !a.atomic) return false;
+ return true;
+ }
+
+ /// register is a storage class and not actually a qualifier
+ /// so it is not preserved by typeof()
+ pub fn inheritFromTypeof(quals: Qualifiers) Qualifiers {
+ var res = quals;
+ res.register = false;
+ return res;
+ }
+
+ pub const Builder = struct {
+ @"const": ?TokenIndex = null,
+ atomic: ?TokenIndex = null,
+ @"volatile": ?TokenIndex = null,
+ restrict: ?TokenIndex = null,
+
+ pub fn finish(b: Qualifiers.Builder, p: *Parser, ty: *Type) !void {
+ if (ty.specifier != .pointer and b.restrict != null) {
+ try p.errStr(.restrict_non_pointer, b.restrict.?, try p.typeStr(ty.*));
+ }
+ if (b.atomic) |some| {
+ if (ty.isArray()) try p.errStr(.atomic_array, some, try p.typeStr(ty.*));
+ if (ty.isFunc()) try p.errStr(.atomic_func, some, try p.typeStr(ty.*));
+ if (ty.hasIncompleteSize()) try p.errStr(.atomic_incomplete, some, try p.typeStr(ty.*));
+ }
+
+ if (b.@"const" != null) ty.qual.@"const" = true;
+ if (b.atomic != null) ty.qual.atomic = true;
+ if (b.@"volatile" != null) ty.qual.@"volatile" = true;
+ if (b.restrict != null) ty.qual.restrict = true;
+ }
+ };
+};
+
+// TODO improve memory usage
+pub const Func = struct {
+ return_type: Type,
+ params: []Param,
+
+ pub const Param = struct {
+ ty: Type,
+ name: StringId,
+ name_tok: TokenIndex,
+ };
+};
+
+pub const Array = struct {
+ len: u64,
+ elem: Type,
+};
+
+pub const Expr = struct {
+ node: NodeIndex,
+ ty: Type,
+};
+
+pub const Attributed = struct {
+ attributes: []Attribute,
+ base: Type,
+
+ pub fn create(allocator: std.mem.Allocator, base: Type, existing_attributes: []const Attribute, attributes: []const Attribute) !*Attributed {
+ var attributed_type = try allocator.create(Attributed);
+ errdefer allocator.destroy(attributed_type);
+
+ var all_attrs = try allocator.alloc(Attribute, existing_attributes.len + attributes.len);
+ std.mem.copy(Attribute, all_attrs, existing_attributes);
+ std.mem.copy(Attribute, all_attrs[existing_attributes.len..], attributes);
+
+ attributed_type.* = .{
+ .attributes = all_attrs,
+ .base = base,
+ };
+ return attributed_type;
+ }
+};
+
+// TODO improve memory usage
+pub const Enum = struct {
+ fields: []Field,
+ tag_ty: Type,
+ name: StringId,
+ fixed: bool,
+
+ pub const Field = struct {
+ ty: Type,
+ name: StringId,
+ name_tok: TokenIndex,
+ node: NodeIndex,
+ };
+
+ pub fn isIncomplete(e: Enum) bool {
+ return e.fields.len == std.math.maxInt(usize);
+ }
+
+ pub fn create(allocator: std.mem.Allocator, name: StringId, fixed_ty: ?Type) !*Enum {
+ var e = try allocator.create(Enum);
+ e.name = name;
+ e.fields.len = std.math.maxInt(usize);
+ if (fixed_ty) |some| e.tag_ty = some;
+ e.fixed = fixed_ty != null;
+ return e;
+ }
+};
+
+// might not need all 4 of these when finished,
+// but currently it helps having all 4 when diff-ing
+// the rust code.
+pub const TypeLayout = struct {
+ /// The size of the type in bits.
+ ///
+ /// This is the value returned by `sizeof` and C and `std::mem::size_of` in Rust
+ /// (but in bits instead of bytes). This is a multiple of `pointer_alignment_bits`.
+ size_bits: u64,
+ /// The alignment of the type, in bits, when used as a field in a record.
+ ///
+ /// This is usually the value returned by `_Alignof` in C, but there are some edge
+ /// cases in GCC where `_Alignof` returns a smaller value.
+ field_alignment_bits: u32,
+ /// The alignment, in bits, of valid pointers to this type.
+ ///
+ /// This is the value returned by `std::mem::align_of` in Rust
+ /// (but in bits instead of bytes). `size_bits` is a multiple of this value.
+ pointer_alignment_bits: u32,
+ /// The required alignment of the type in bits.
+ ///
+ /// This value is only used by MSVC targets. It is 8 on all other
+ /// targets. On MSVC targets, this value restricts the effects of `#pragma pack` except
+ /// in some cases involving bit-fields.
+ required_alignment_bits: u32,
+};
+
+pub const FieldLayout = struct {
+ /// `offset_bits` and `size_bits` should both be INVALID if and only if the field
+ /// is an unnamed bitfield. There is no way to reference an unnamed bitfield in C, so
+ /// there should be no way to observe these values. If it is used, this value will
+ /// maximize the chance that a safety-checked overflow will occur.
+ const INVALID = std.math.maxInt(u64);
+
+ /// The offset of the field, in bits, from the start of the struct.
+ offset_bits: u64 = INVALID,
+ /// The size, in bits, of the field.
+ ///
+ /// For bit-fields, this is the width of the field.
+ size_bits: u64 = INVALID,
+
+ pub fn isUnnamed(self: FieldLayout) bool {
+ return self.offset_bits == INVALID and self.size_bits == INVALID;
+ }
+};
+
+// TODO improve memory usage
+pub const Record = struct {
+ fields: []Field,
+ type_layout: TypeLayout,
+ /// If this is null, none of the fields have attributes
+ /// Otherwise, it's a pointer to N items (where N == number of fields)
+ /// and the item at index i is the attributes for the field at index i
+ field_attributes: ?[*][]const Attribute,
+ name: StringId,
+
+ pub const Field = struct {
+ ty: Type,
+ name: StringId,
+ /// zero for anonymous fields
+ name_tok: TokenIndex = 0,
+ bit_width: ?u32 = null,
+ layout: FieldLayout = .{
+ .offset_bits = 0,
+ .size_bits = 0,
+ },
+
+ pub fn isNamed(f: *const Field) bool {
+ return f.name_tok != 0;
+ }
+
+ pub fn isAnonymousRecord(f: Field) bool {
+ return !f.isNamed() and f.ty.isRecord();
+ }
+
+ /// false for bitfields
+ pub fn isRegularField(f: *const Field) bool {
+ return f.bit_width == null;
+ }
+
+ /// bit width as specified in the C source. Asserts that `f` is a bitfield.
+ pub fn specifiedBitWidth(f: *const Field) u32 {
+ return f.bit_width.?;
+ }
+ };
+
+ pub fn isIncomplete(r: Record) bool {
+ return r.fields.len == std.math.maxInt(usize);
+ }
+
+ pub fn create(allocator: std.mem.Allocator, name: StringId) !*Record {
+ var r = try allocator.create(Record);
+ r.name = name;
+ r.fields.len = std.math.maxInt(usize);
+ r.field_attributes = null;
+ r.type_layout = .{
+ .size_bits = 8,
+ .field_alignment_bits = 8,
+ .pointer_alignment_bits = 8,
+ .required_alignment_bits = 8,
+ };
+ return r;
+ }
+
+ pub fn hasFieldOfType(self: *const Record, ty: Type, comp: *const Compilation) bool {
+ if (self.isIncomplete()) return false;
+ for (self.fields) |f| {
+ if (ty.eql(f.ty, comp, false)) return true;
+ }
+ return false;
+ }
+};
+
+pub const Specifier = enum {
+ /// A NaN-like poison value
+ invalid,
+
+ /// GNU auto type
+ /// This is a placeholder specifier - it must be replaced by the actual type specifier (determined by the initializer)
+ auto_type,
+
+ void,
+ bool,
+
+ // integers
+ char,
+ schar,
+ uchar,
+ short,
+ ushort,
+ int,
+ uint,
+ long,
+ ulong,
+ long_long,
+ ulong_long,
+ int128,
+ uint128,
+ complex_char,
+ complex_schar,
+ complex_uchar,
+ complex_short,
+ complex_ushort,
+ complex_int,
+ complex_uint,
+ complex_long,
+ complex_ulong,
+ complex_long_long,
+ complex_ulong_long,
+ complex_int128,
+ complex_uint128,
+
+ // data.int
+ bit_int,
+ complex_bit_int,
+
+ // floating point numbers
+ fp16,
+ float16,
+ float,
+ double,
+ long_double,
+ float80,
+ float128,
+ complex_float,
+ complex_double,
+ complex_long_double,
+ complex_float80,
+ complex_float128,
+
+ // data.sub_type
+ pointer,
+ unspecified_variable_len_array,
+ decayed_unspecified_variable_len_array,
+ // data.func
+ /// int foo(int bar, char baz) and int (void)
+ func,
+ /// int foo(int bar, char baz, ...)
+ var_args_func,
+ /// int foo(bar, baz) and int foo()
+ /// is also var args, but we can give warnings about incorrect amounts of parameters
+ old_style_func,
+
+ // data.array
+ array,
+ decayed_array,
+ static_array,
+ decayed_static_array,
+ incomplete_array,
+ decayed_incomplete_array,
+ vector,
+ // data.expr
+ variable_len_array,
+ decayed_variable_len_array,
+
+ // data.record
+ @"struct",
+ @"union",
+
+ // data.enum
+ @"enum",
+
+ /// typeof(type-name)
+ typeof_type,
+ /// decayed array created with typeof(type-name)
+ decayed_typeof_type,
+
+ /// typeof(expression)
+ typeof_expr,
+ /// decayed array created with typeof(expression)
+ decayed_typeof_expr,
+
+ /// data.attributed
+ attributed,
+
+ /// C23 nullptr_t
+ nullptr_t,
+};
+
+/// All fields of Type except data may be mutated
+data: union {
+ sub_type: *Type,
+ func: *Func,
+ array: *Array,
+ expr: *Expr,
+ @"enum": *Enum,
+ record: *Record,
+ attributed: *Attributed,
+ none: void,
+ int: struct {
+ bits: u8,
+ signedness: std.builtin.Signedness,
+ },
+} = .{ .none = {} },
+specifier: Specifier,
+qual: Qualifiers = .{},
+
+pub const int = Type{ .specifier = .int };
+pub const invalid = Type{ .specifier = .invalid };
+
+/// Determine if type matches the given specifier, recursing into typeof
+/// types if necessary.
+pub fn is(ty: Type, specifier: Specifier) bool {
+ std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
+ return ty.get(specifier) != null;
+}
+
+pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type {
+ if (attributes.len == 0) return self;
+ const attributed_type = try Type.Attributed.create(allocator, self, self.getAttributes(), attributes);
+ return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } };
+}
+
+pub fn isCallable(ty: Type) ?Type {
+ return switch (ty.specifier) {
+ .func, .var_args_func, .old_style_func => ty,
+ .pointer => if (ty.data.sub_type.isFunc()) ty.data.sub_type.* else null,
+ .typeof_type => ty.data.sub_type.isCallable(),
+ .typeof_expr => ty.data.expr.ty.isCallable(),
+ .attributed => ty.data.attributed.base.isCallable(),
+ else => null,
+ };
+}
+
+pub fn isFunc(ty: Type) bool {
+ return switch (ty.specifier) {
+ .func, .var_args_func, .old_style_func => true,
+ .typeof_type => ty.data.sub_type.isFunc(),
+ .typeof_expr => ty.data.expr.ty.isFunc(),
+ .attributed => ty.data.attributed.base.isFunc(),
+ else => false,
+ };
+}
+
+pub fn isArray(ty: Type) bool {
+ return switch (ty.specifier) {
+ .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => true,
+ .typeof_type => ty.data.sub_type.isArray(),
+ .typeof_expr => ty.data.expr.ty.isArray(),
+ .attributed => ty.data.attributed.base.isArray(),
+ else => false,
+ };
+}
+
+pub fn isScalar(ty: Type) bool {
+ return ty.isInt() or ty.isScalarNonInt();
+}
+
+/// To avoid calling isInt() twice for allowable loop/if controlling expressions
+pub fn isScalarNonInt(ty: Type) bool {
+ return ty.isFloat() or ty.isPtr() or ty.is(.nullptr_t);
+}
+
+pub fn isDecayed(ty: Type) bool {
+ const decayed = switch (ty.specifier) {
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ .decayed_typeof_type,
+ .decayed_typeof_expr,
+ => true,
+ else => false,
+ };
+ std.debug.assert(decayed or !std.mem.startsWith(u8, @tagName(ty.specifier), "decayed"));
+ return decayed;
+}
+
+pub fn isPtr(ty: Type) bool {
+ return switch (ty.specifier) {
+ .pointer,
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ .decayed_typeof_type,
+ .decayed_typeof_expr,
+ => true,
+ .typeof_type => ty.data.sub_type.isPtr(),
+ .typeof_expr => ty.data.expr.ty.isPtr(),
+ .attributed => ty.data.attributed.base.isPtr(),
+ else => false,
+ };
+}
+
+pub fn isInt(ty: Type) bool {
+ return switch (ty.specifier) {
+ // zig fmt: off
+ .@"enum", .bool, .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong,
+ .long_long, .ulong_long, .int128, .uint128, .complex_char, .complex_schar, .complex_uchar,
+ .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+ .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+ .bit_int, .complex_bit_int => true,
+ // zig fmt: on
+ .typeof_type => ty.data.sub_type.isInt(),
+ .typeof_expr => ty.data.expr.ty.isInt(),
+ .attributed => ty.data.attributed.base.isInt(),
+ else => false,
+ };
+}
+
+pub fn isFloat(ty: Type) bool {
+ return switch (ty.specifier) {
+ // zig fmt: off
+ .float, .double, .long_double, .complex_float, .complex_double, .complex_long_double,
+ .fp16, .float16, .float80, .float128, .complex_float80, .complex_float128 => true,
+ // zig fmt: on
+ .typeof_type => ty.data.sub_type.isFloat(),
+ .typeof_expr => ty.data.expr.ty.isFloat(),
+ .attributed => ty.data.attributed.base.isFloat(),
+ else => false,
+ };
+}
+
+pub fn isReal(ty: Type) bool {
+ return switch (ty.specifier) {
+ // zig fmt: off
+ .complex_float, .complex_double, .complex_long_double, .complex_float80,
+ .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
+ .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+ .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+ .complex_bit_int => false,
+ // zig fmt: on
+ .typeof_type => ty.data.sub_type.isReal(),
+ .typeof_expr => ty.data.expr.ty.isReal(),
+ .attributed => ty.data.attributed.base.isReal(),
+ else => true,
+ };
+}
+
+pub fn isComplex(ty: Type) bool {
+ return switch (ty.specifier) {
+ // zig fmt: off
+ .complex_float, .complex_double, .complex_long_double, .complex_float80,
+ .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
+ .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+ .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+ .complex_bit_int => true,
+ // zig fmt: on
+ .typeof_type => ty.data.sub_type.isComplex(),
+ .typeof_expr => ty.data.expr.ty.isComplex(),
+ .attributed => ty.data.attributed.base.isComplex(),
+ else => false,
+ };
+}
+
+pub fn isVoidStar(ty: Type) bool {
+ return switch (ty.specifier) {
+ .pointer => ty.data.sub_type.specifier == .void,
+ .typeof_type => ty.data.sub_type.isVoidStar(),
+ .typeof_expr => ty.data.expr.ty.isVoidStar(),
+ .attributed => ty.data.attributed.base.isVoidStar(),
+ else => false,
+ };
+}
+
+pub fn isTypeof(ty: Type) bool {
+ return switch (ty.specifier) {
+ .typeof_type, .typeof_expr, .decayed_typeof_type, .decayed_typeof_expr => true,
+ else => false,
+ };
+}
+
+pub fn isConst(ty: Type) bool {
+ return switch (ty.specifier) {
+ .typeof_type, .decayed_typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(),
+ .typeof_expr, .decayed_typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(),
+ .attributed => ty.data.attributed.base.isConst(),
+ else => ty.qual.@"const",
+ };
+}
+
+pub fn isUnsignedInt(ty: Type, comp: *const Compilation) bool {
+ return switch (ty.specifier) {
+ // zig fmt: off
+ .char, .complex_char => return comp.getCharSignedness() == .unsigned,
+ .uchar, .ushort, .uint, .ulong, .ulong_long, .bool, .complex_uchar, .complex_ushort,
+ .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => true,
+ // zig fmt: on
+ .bit_int, .complex_bit_int => return ty.data.int.signedness == .unsigned,
+ .typeof_type => ty.data.sub_type.isUnsignedInt(comp),
+ .typeof_expr => ty.data.expr.ty.isUnsignedInt(comp),
+ .attributed => ty.data.attributed.base.isUnsignedInt(comp),
+ else => false,
+ };
+}
+
+pub fn isEnumOrRecord(ty: Type) bool {
+ return switch (ty.specifier) {
+ .@"enum", .@"struct", .@"union" => true,
+ .typeof_type => ty.data.sub_type.isEnumOrRecord(),
+ .typeof_expr => ty.data.expr.ty.isEnumOrRecord(),
+ .attributed => ty.data.attributed.base.isEnumOrRecord(),
+ else => false,
+ };
+}
+
+pub fn isRecord(ty: Type) bool {
+ return switch (ty.specifier) {
+ .@"struct", .@"union" => true,
+ .typeof_type => ty.data.sub_type.isRecord(),
+ .typeof_expr => ty.data.expr.ty.isRecord(),
+ .attributed => ty.data.attributed.base.isRecord(),
+ else => false,
+ };
+}
+
+pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool {
+ return switch (ty.specifier) {
+ // anonymous records can be recognized by their names which are in
+ // the format "(anonymous TAG at path:line:col)".
+ .@"struct", .@"union" => {
+ const mapper = comp.string_interner.getSlowTypeMapper();
+ return mapper.lookup(ty.data.record.name)[0] == '(';
+ },
+ .typeof_type => ty.data.sub_type.isAnonymousRecord(comp),
+ .typeof_expr => ty.data.expr.ty.isAnonymousRecord(comp),
+ .attributed => ty.data.attributed.base.isAnonymousRecord(comp),
+ else => false,
+ };
+}
+
+pub fn elemType(ty: Type) Type {
+ return switch (ty.specifier) {
+ .pointer, .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => ty.data.sub_type.*,
+ .array, .static_array, .incomplete_array, .decayed_array, .decayed_static_array, .decayed_incomplete_array, .vector => ty.data.array.elem,
+ .variable_len_array, .decayed_variable_len_array => ty.data.expr.ty,
+ .typeof_type, .decayed_typeof_type, .typeof_expr, .decayed_typeof_expr => {
+ const unwrapped = ty.canonicalize(.preserve_quals);
+ var elem = unwrapped.elemType();
+ elem.qual = elem.qual.mergeAll(unwrapped.qual);
+ return elem;
+ },
+ .attributed => ty.data.attributed.base,
+ .invalid => Type.invalid,
+ // zig fmt: off
+ .complex_float, .complex_double, .complex_long_double, .complex_float80,
+ .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
+ .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+ .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+ .complex_bit_int => ty.makeReal(),
+ // zig fmt: on
+ else => unreachable,
+ };
+}
+
+pub fn returnType(ty: Type) Type {
+ return switch (ty.specifier) {
+ .func, .var_args_func, .old_style_func => ty.data.func.return_type,
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.returnType(),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.returnType(),
+ .attributed => ty.data.attributed.base.returnType(),
+ .invalid => Type.invalid,
+ else => unreachable,
+ };
+}
+
+pub fn params(ty: Type) []Func.Param {
+ return switch (ty.specifier) {
+ .func, .var_args_func, .old_style_func => ty.data.func.params,
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.params(),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.params(),
+ .attributed => ty.data.attributed.base.params(),
+ .invalid => &.{},
+ else => unreachable,
+ };
+}
+
+pub fn arrayLen(ty: Type) ?u64 {
+ return switch (ty.specifier) {
+ .array, .static_array, .decayed_array, .decayed_static_array => ty.data.array.len,
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.arrayLen(),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.arrayLen(),
+ .attributed => ty.data.attributed.base.arrayLen(),
+ else => null,
+ };
+}
+
+/// Complex numbers are scalars but they can be initialized with a 2-element initList
+pub fn expectedInitListSize(ty: Type) ?u64 {
+ return if (ty.isComplex()) 2 else ty.arrayLen();
+}
+
+pub fn anyQual(ty: Type) bool {
+ return switch (ty.specifier) {
+ .typeof_type => ty.qual.any() or ty.data.sub_type.anyQual(),
+ .typeof_expr => ty.qual.any() or ty.data.expr.ty.anyQual(),
+ else => ty.qual.any(),
+ };
+}
+
+pub fn getAttributes(ty: Type) []const Attribute {
+ return switch (ty.specifier) {
+ .attributed => ty.data.attributed.attributes,
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.getAttributes(),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getAttributes(),
+ else => &.{},
+ };
+}
+
+pub fn getRecord(ty: Type) ?*const Type.Record {
+ return switch (ty.specifier) {
+ .attributed => ty.data.attributed.base.getRecord(),
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.getRecord(),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getRecord(),
+ .@"struct", .@"union" => ty.data.record,
+ else => null,
+ };
+}
+
+fn compareIntegerRanks(a: Type, b: Type, comp: *const Compilation) std.math.Order {
+ std.debug.assert(a.isInt() and b.isInt());
+ if (a.eql(b, comp, false)) return .eq;
+
+ const a_unsigned = a.isUnsignedInt(comp);
+ const b_unsigned = b.isUnsignedInt(comp);
+
+ const a_rank = a.integerRank(comp);
+ const b_rank = b.integerRank(comp);
+ if (a_unsigned == b_unsigned) {
+ return std.math.order(a_rank, b_rank);
+ }
+ if (a_unsigned) {
+ if (a_rank >= b_rank) return .gt;
+ return .lt;
+ }
+ std.debug.assert(b_unsigned);
+ if (b_rank >= a_rank) return .lt;
+ return .gt;
+}
+
+fn realIntegerConversion(a: Type, b: Type, comp: *const Compilation) Type {
+ std.debug.assert(a.isReal() and b.isReal());
+ const type_order = a.compareIntegerRanks(b, comp);
+ const a_signed = !a.isUnsignedInt(comp);
+ const b_signed = !b.isUnsignedInt(comp);
+ if (a_signed == b_signed) {
+ // If both have the same sign, use higher-rank type.
+ return switch (type_order) {
+ .lt => b,
+ .eq, .gt => a,
+ };
+ } else if (type_order != if (a_signed) std.math.Order.gt else std.math.Order.lt) {
+ // Only one is signed; and the unsigned type has rank >= the signed type
+ // Use the unsigned type
+ return if (b_signed) a else b;
+ } else if (a.bitSizeof(comp).? != b.bitSizeof(comp).?) {
+ // Signed type is higher rank and sizes are not equal
+ // Use the signed type
+ return if (a_signed) a else b;
+ } else {
+ // Signed type is higher rank but same size as unsigned type
+ // e.g. `long` and `unsigned` on x86-linux-gnu
+ // Use unsigned version of the signed type
+ return if (a_signed) a.makeIntegerUnsigned() else b.makeIntegerUnsigned();
+ }
+}
+
+pub fn makeIntegerUnsigned(ty: Type) Type {
+ // TODO discards attributed/typeof
+ var base = ty.canonicalize(.standard);
+ switch (base.specifier) {
+ // zig fmt: off
+ .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128,
+ .complex_uchar, .complex_ushort, .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128,
+ => return ty,
+ // zig fmt: on
+
+ .char, .complex_char => {
+ base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 2);
+ return base;
+ },
+
+ // zig fmt: off
+ .schar, .short, .int, .long, .long_long, .int128,
+ .complex_schar, .complex_short, .complex_int, .complex_long, .complex_long_long, .complex_int128 => {
+ base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 1);
+ return base;
+ },
+ // zig fmt: on
+
+ .bit_int, .complex_bit_int => {
+ base.data.int.signedness = .unsigned;
+ return base;
+ },
+ else => unreachable,
+ }
+}
+
+/// Find the common type of a and b for binary operations
+pub fn integerConversion(a: Type, b: Type, comp: *const Compilation) Type {
+ const a_real = a.isReal();
+ const b_real = b.isReal();
+ const target_ty = a.makeReal().realIntegerConversion(b.makeReal(), comp);
+ return if (a_real and b_real) target_ty else target_ty.makeComplex();
+}
+
+pub fn integerPromotion(ty: Type, comp: *Compilation) Type {
+ var specifier = ty.specifier;
+ switch (specifier) {
+ .@"enum" => {
+ if (ty.hasIncompleteSize()) return .{ .specifier = .int };
+ specifier = ty.data.@"enum".tag_ty.specifier;
+ },
+ .bit_int, .complex_bit_int => return .{ .specifier = specifier, .data = ty.data },
+ else => {},
+ }
+ return switch (specifier) {
+ else => .{
+ .specifier = switch (specifier) {
+ // zig fmt: off
+ .bool, .char, .schar, .uchar, .short => .int,
+ .ushort => if (ty.sizeof(comp).? == sizeof(.{ .specifier = .int }, comp)) Specifier.uint else .int,
+ .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128, .complex_char,
+ .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
+ .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
+ .complex_int128, .complex_uint128 => specifier,
+ // zig fmt: on
+ .typeof_type => return ty.data.sub_type.integerPromotion(comp),
+ .typeof_expr => return ty.data.expr.ty.integerPromotion(comp),
+ .attributed => return ty.data.attributed.base.integerPromotion(comp),
+ .invalid => .invalid,
+ else => unreachable, // _BitInt, or not an integer type
+ },
+ },
+ };
+}
+
+/// Promote a bitfield. If `int` can hold all the values of the underlying field,
+/// promote to int. Otherwise, promote to unsigned int
+/// Returns null if no promotion is necessary
+pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type {
+ const type_size_bits = ty.bitSizeof(comp).?;
+
+ // Note: GCC and clang will promote `long: 3` to int even though the C standard does not allow this
+ if (width < type_size_bits) {
+ return int;
+ }
+
+ if (width == type_size_bits) {
+ return if (ty.isUnsignedInt(comp)) .{ .specifier = .uint } else int;
+ }
+
+ return null;
+}
+
+pub fn hasIncompleteSize(ty: Type) bool {
+ return switch (ty.specifier) {
+ .void, .incomplete_array, .invalid => true,
+ .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed,
+ .@"struct", .@"union" => ty.data.record.isIncomplete(),
+ .array, .static_array => ty.data.array.elem.hasIncompleteSize(),
+ .typeof_type => ty.data.sub_type.hasIncompleteSize(),
+ .typeof_expr => ty.data.expr.ty.hasIncompleteSize(),
+ .attributed => ty.data.attributed.base.hasIncompleteSize(),
+ else => false,
+ };
+}
+
+pub fn hasUnboundVLA(ty: Type) bool {
+ var cur = ty;
+ while (true) {
+ switch (cur.specifier) {
+ .unspecified_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ => return true,
+ .array,
+ .static_array,
+ .incomplete_array,
+ .variable_len_array,
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ => cur = cur.elemType(),
+ .typeof_type, .decayed_typeof_type => cur = cur.data.sub_type.*,
+ .typeof_expr, .decayed_typeof_expr => cur = cur.data.expr.ty,
+ .attributed => cur = cur.data.attributed.base,
+ else => return false,
+ }
+ }
+}
+
+pub fn hasField(ty: Type, name: StringId) bool {
+ switch (ty.specifier) {
+ .@"struct" => {
+ std.debug.assert(!ty.data.record.isIncomplete());
+ for (ty.data.record.fields) |f| {
+ if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
+ if (name == f.name) return true;
+ }
+ },
+ .@"union" => {
+ std.debug.assert(!ty.data.record.isIncomplete());
+ for (ty.data.record.fields) |f| {
+ if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
+ if (name == f.name) return true;
+ }
+ },
+ .typeof_type => return ty.data.sub_type.hasField(name),
+ .typeof_expr => return ty.data.expr.ty.hasField(name),
+ .attributed => return ty.data.attributed.base.hasField(name),
+ .invalid => return false,
+ else => unreachable,
+ }
+ return false;
+}
+
+pub fn minInt(ty: Type, comp: *const Compilation) i64 {
+ std.debug.assert(ty.isInt());
+ if (ty.isUnsignedInt(comp)) return 0;
+ return switch (ty.sizeof(comp).?) {
+ 1 => std.math.minInt(i8),
+ 2 => std.math.minInt(i16),
+ 4 => std.math.minInt(i32),
+ 8 => std.math.minInt(i64),
+ else => unreachable,
+ };
+}
+
+pub fn maxInt(ty: Type, comp: *const Compilation) u64 {
+ std.debug.assert(ty.isInt());
+ return switch (ty.sizeof(comp).?) {
+ 1 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u8)) else std.math.maxInt(i8),
+ 2 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u16)) else std.math.maxInt(i16),
+ 4 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u32)) else std.math.maxInt(i32),
+ 8 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u64)) else std.math.maxInt(i64),
+ else => unreachable,
+ };
+}
+
+const TypeSizeOrder = enum {
+ lt,
+ gt,
+ eq,
+ indeterminate,
+};
+
+pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder {
+ const a_size = a.sizeof(comp) orelse return .indeterminate;
+ const b_size = b.sizeof(comp) orelse return .indeterminate;
+ return switch (std.math.order(a_size, b_size)) {
+ .lt => .lt,
+ .gt => .gt,
+ .eq => .eq,
+ };
+}
+
+/// Size of type as reported by sizeof
+pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
+ return switch (ty.specifier) {
+ .auto_type => unreachable,
+ .variable_len_array, .unspecified_variable_len_array => return null,
+ .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null,
+ .func, .var_args_func, .old_style_func, .void, .bool => 1,
+ .char, .schar, .uchar => 1,
+ .short => comp.target.c_type_byte_size(.short),
+ .ushort => comp.target.c_type_byte_size(.ushort),
+ .int => comp.target.c_type_byte_size(.int),
+ .uint => comp.target.c_type_byte_size(.uint),
+ .long => comp.target.c_type_byte_size(.long),
+ .ulong => comp.target.c_type_byte_size(.ulong),
+ .long_long => comp.target.c_type_byte_size(.longlong),
+ .ulong_long => comp.target.c_type_byte_size(.ulonglong),
+ .long_double => comp.target.c_type_byte_size(.longdouble),
+ .int128, .uint128 => 16,
+ .fp16, .float16 => 2,
+ .float => comp.target.c_type_byte_size(.float),
+ .double => comp.target.c_type_byte_size(.double),
+ .float80 => 16,
+ .float128 => 16,
+ .bit_int => {
+ return std.mem.alignForward(u64, (ty.data.int.bits + 7) / 8, ty.alignof(comp));
+ },
+ // zig fmt: off
+ .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
+ .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
+ .complex_int128, .complex_uint128, .complex_float, .complex_double,
+ .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
+ => return 2 * ty.makeReal().sizeof(comp).?,
+ // zig fmt: on
+ .pointer,
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ .decayed_typeof_type,
+ .decayed_typeof_expr,
+ .static_array,
+ .nullptr_t,
+ => comp.target.ptrBitWidth() / 8,
+ .array, .vector => {
+ const size = ty.data.array.elem.sizeof(comp) orelse return null;
+ const arr_size = size * ty.data.array.len;
+ if (comp.langopts.emulate == .msvc) {
+ // msvc ignores array type alignment.
+ // Since the size might not be a multiple of the field
+ // alignment, the address of the second element might not be properly aligned
+ // for the field alignment. A flexible array has size 0. See test case 0018.
+ return arr_size;
+ } else {
+ return std.mem.alignForward(u64, arr_size, ty.alignof(comp));
+ }
+ },
+ .@"struct", .@"union" => if (ty.data.record.isIncomplete()) null else @as(u64, ty.data.record.type_layout.size_bits / 8),
+ .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) null else ty.data.@"enum".tag_ty.sizeof(comp),
+ .typeof_type => ty.data.sub_type.sizeof(comp),
+ .typeof_expr => ty.data.expr.ty.sizeof(comp),
+ .attributed => ty.data.attributed.base.sizeof(comp),
+ .invalid => return null,
+ };
+}
+
+pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {
+ return switch (ty.specifier) {
+ .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1,
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.bitSizeof(comp),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.bitSizeof(comp),
+ .attributed => ty.data.attributed.base.bitSizeof(comp),
+ .bit_int => return ty.data.int.bits,
+ .long_double => comp.target.c_type_bit_size(.longdouble),
+ .float80 => return 80,
+ else => 8 * (ty.sizeof(comp) orelse return null),
+ };
+}
+
+pub fn alignable(ty: Type) bool {
+ return ty.isArray() or !ty.hasIncompleteSize() or ty.is(.void);
+}
+
+/// Get the alignment of a type
+pub fn alignof(ty: Type, comp: *const Compilation) u29 {
+ // don't return the attribute for records
+ // layout has already accounted for requested alignment
+ if (ty.requestedAlignment(comp)) |requested| {
+ // gcc does not respect alignment on enums
+ if (ty.get(.@"enum")) |ty_enum| {
+ if (comp.langopts.emulate == .gcc) {
+ return ty_enum.alignof(comp);
+ }
+ } else if (ty.getRecord()) |rec| {
+ if (ty.hasIncompleteSize()) return 0;
+ const computed: u29 = @intCast(@divExact(rec.type_layout.field_alignment_bits, 8));
+ return @max(requested, computed);
+ } else if (comp.langopts.emulate == .msvc) {
+ const type_align = ty.data.attributed.base.alignof(comp);
+ return @max(requested, type_align);
+ }
+ return requested;
+ }
+
+ return switch (ty.specifier) {
+ .invalid => unreachable,
+ .auto_type => unreachable,
+
+ .variable_len_array,
+ .incomplete_array,
+ .unspecified_variable_len_array,
+ .array,
+ .vector,
+ => ty.elemType().alignof(comp),
+ .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target),
+ .char, .schar, .uchar, .void, .bool => 1,
+
+ // zig fmt: off
+ .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
+ .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
+ .complex_int128, .complex_uint128, .complex_float, .complex_double,
+ .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
+ => return ty.makeReal().alignof(comp),
+ // zig fmt: on
+
+ .short => comp.target.c_type_alignment(.short),
+ .ushort => comp.target.c_type_alignment(.ushort),
+ .int => comp.target.c_type_alignment(.int),
+ .uint => comp.target.c_type_alignment(.uint),
+
+ .long => comp.target.c_type_alignment(.long),
+ .ulong => comp.target.c_type_alignment(.ulong),
+ .long_long => comp.target.c_type_alignment(.longlong),
+ .ulong_long => comp.target.c_type_alignment(.ulonglong),
+
+ .bit_int => @min(
+ std.math.ceilPowerOfTwoPromote(u16, (ty.data.int.bits + 7) / 8),
+ comp.target.maxIntAlignment(),
+ ),
+
+ .float => comp.target.c_type_alignment(.float),
+ .double => comp.target.c_type_alignment(.double),
+ .long_double => comp.target.c_type_alignment(.longdouble),
+
+ .int128, .uint128 => if (comp.target.cpu.arch == .s390x and comp.target.os.tag == .linux and comp.target.isGnu()) 8 else 16,
+ .fp16, .float16 => 2,
+
+ .float80, .float128 => 16,
+ .pointer,
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ .static_array,
+ .nullptr_t,
+ => switch (comp.target.cpu.arch) {
+ .avr => 1,
+ else => comp.target.ptrBitWidth() / 8,
+ },
+ .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8),
+ .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp),
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.alignof(comp),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.alignof(comp),
+ .attributed => ty.data.attributed.base.alignof(comp),
+ };
+}
+
+/// Canonicalize a possibly-typeof() type. If the type is not a typeof() type, simply
+/// return it. Otherwise, determine the actual qualified type.
+/// The `qual_handling` parameter can be used to return the full set of qualifiers
+/// added by typeof() operations, which is useful when determining the elemType of
+/// arrays and pointers.
+pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {
+ var cur = ty;
+ if (cur.specifier == .attributed) cur = cur.data.attributed.base;
+ if (!cur.isTypeof()) return cur;
+
+ var qual = cur.qual;
+ while (true) {
+ switch (cur.specifier) {
+ .typeof_type => cur = cur.data.sub_type.*,
+ .typeof_expr => cur = cur.data.expr.ty,
+ .decayed_typeof_type => {
+ cur = cur.data.sub_type.*;
+ cur.decayArray();
+ },
+ .decayed_typeof_expr => {
+ cur = cur.data.expr.ty;
+ cur.decayArray();
+ },
+ else => break,
+ }
+ qual = qual.mergeAll(cur.qual);
+ }
+ if ((cur.isArray() or cur.isPtr()) and qual_handling == .standard) {
+ cur.qual = .{};
+ } else {
+ cur.qual = qual;
+ }
+ return cur;
+}
+
+pub fn get(ty: *const Type, specifier: Specifier) ?*const Type {
+ std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
+ return switch (ty.specifier) {
+ .typeof_type => ty.data.sub_type.get(specifier),
+ .typeof_expr => ty.data.expr.ty.get(specifier),
+ .attributed => ty.data.attributed.base.get(specifier),
+ else => if (ty.specifier == specifier) ty else null,
+ };
+}
+
+pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 {
+ return switch (ty.specifier) {
+ .typeof_type, .decayed_typeof_type => ty.data.sub_type.requestedAlignment(comp),
+ .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.requestedAlignment(comp),
+ .attributed => annotationAlignment(comp, ty.data.attributed.attributes),
+ else => null,
+ };
+}
+
+pub fn enumIsPacked(ty: Type, comp: *const Compilation) bool {
+ std.debug.assert(ty.is(.@"enum"));
+ return comp.langopts.short_enums or target_util.packAllEnums(comp.target) or ty.hasAttribute(.@"packed");
+}
+
+pub fn annotationAlignment(comp: *const Compilation, attrs: ?[]const Attribute) ?u29 {
+ const a = attrs orelse return null;
+
+ var max_requested: ?u29 = null;
+ for (a) |attribute| {
+ if (attribute.tag != .aligned) continue;
+ const requested = if (attribute.args.aligned.alignment) |alignment| alignment.requested else target_util.defaultAlignment(comp.target);
+ if (max_requested == null or max_requested.? < requested) {
+ max_requested = requested;
+ }
+ }
+ return max_requested;
+}
+
+/// Checks type compatibility for __builtin_types_compatible_p
+/// Returns true if the unqualified version of `a_param` and `b_param` are the same
+/// Ignores top-level qualifiers (e.g. `int` and `const int` are compatible) but `int *` and `const int *` are not
+/// Two types that are typedefed are considered compatible if their underlying types are compatible.
+/// An enum type is not considered to be compatible with another enum type even if both are compatible with the same integer type;
+/// `A[]` and `A[N]` for a type `A` and integer `N` are compatible
+pub fn compatible(a_param: Type, b_param: Type, comp: *const Compilation) bool {
+ var a_unqual = a_param.canonicalize(.standard);
+ a_unqual.qual.@"const" = false;
+ a_unqual.qual.@"volatile" = false;
+ var b_unqual = b_param.canonicalize(.standard);
+ b_unqual.qual.@"const" = false;
+ b_unqual.qual.@"volatile" = false;
+
+ if (a_unqual.eql(b_unqual, comp, true)) return true;
+ if (!a_unqual.isArray() or !b_unqual.isArray()) return false;
+
+ if (a_unqual.arrayLen() == null or b_unqual.arrayLen() == null) {
+ // incomplete arrays are compatible with arrays of the same element type
+ // GCC and clang ignore cv-qualifiers on arrays
+ return a_unqual.elemType().compatible(b_unqual.elemType(), comp);
+ }
+ return false;
+}
+
+pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifiers: bool) bool {
+ const a = a_param.canonicalize(.standard);
+ const b = b_param.canonicalize(.standard);
+
+ if (a.specifier == .invalid or b.specifier == .invalid) return false;
+ if (a.alignof(comp) != b.alignof(comp)) return false;
+ if (a.isPtr()) {
+ if (!b.isPtr()) return false;
+ } else if (a.isFunc()) {
+ if (!b.isFunc()) return false;
+ } else if (a.isArray()) {
+ if (!b.isArray()) return false;
+ } else if (a.specifier != b.specifier) return false;
+
+ if (a.qual.atomic != b.qual.atomic) return false;
+ if (check_qualifiers) {
+ if (a.qual.@"const" != b.qual.@"const") return false;
+ if (a.qual.@"volatile" != b.qual.@"volatile") return false;
+ }
+
+ switch (a.specifier) {
+ .pointer,
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ => if (!a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers)) return false,
+
+ .func,
+ .var_args_func,
+ .old_style_func,
+ => {
+ // TODO validate this
+ if (a.data.func.params.len != b.data.func.params.len) return false;
+ // return type cannot have qualifiers
+ if (!a.returnType().eql(b.returnType(), comp, false)) return false;
+ for (a.data.func.params, b.data.func.params) |param, b_qual| {
+ var a_unqual = param.ty;
+ a_unqual.qual.@"const" = false;
+ a_unqual.qual.@"volatile" = false;
+ var b_unqual = b_qual.ty;
+ b_unqual.qual.@"const" = false;
+ b_unqual.qual.@"volatile" = false;
+ if (!a_unqual.eql(b_unqual, comp, check_qualifiers)) return false;
+ }
+ },
+
+ .array,
+ .static_array,
+ .incomplete_array,
+ .vector,
+ => {
+ if (!std.meta.eql(a.arrayLen(), b.arrayLen())) return false;
+ if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false;
+ },
+ .variable_len_array => if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false,
+
+ .@"struct", .@"union" => if (a.data.record != b.data.record) return false,
+ .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false,
+ .bit_int, .complex_bit_int => return a.data.int.bits == b.data.int.bits and a.data.int.signedness == b.data.int.signedness,
+
+ else => {},
+ }
+ return true;
+}
+
+/// Decays an array to a pointer
+pub fn decayArray(ty: *Type) void {
+ // the decayed array type is the current specifier +1
+ ty.specifier = @enumFromInt(@intFromEnum(ty.specifier) + 1);
+}
+
+pub fn originalTypeOfDecayedArray(ty: Type) Type {
+ std.debug.assert(ty.isDecayed());
+ var copy = ty;
+ copy.specifier = @enumFromInt(@intFromEnum(ty.specifier) - 1);
+ return copy;
+}
+
+/// Rank for floating point conversions, ignoring domain (complex vs real)
+/// Asserts that ty is a floating point type
+pub fn floatRank(ty: Type) usize {
+ const real = ty.makeReal();
+ return switch (real.specifier) {
+ // TODO: bfloat16 => 0
+ .float16 => 1,
+ .fp16 => 2,
+ .float => 3,
+ .double => 4,
+ .long_double => 5,
+ .float128 => 6,
+ // TODO: ibm128 => 7
+ else => unreachable,
+ };
+}
+
+/// Rank for integer conversions, ignoring domain (complex vs real)
+/// Asserts that ty is an integer type
+pub fn integerRank(ty: Type, comp: *const Compilation) usize {
+ const real = ty.makeReal();
+ return @intCast(switch (real.specifier) {
+ .bit_int => @as(u64, real.data.int.bits) << 3,
+
+ .bool => 1 + (ty.bitSizeof(comp).? << 3),
+ .char, .schar, .uchar => 2 + (ty.bitSizeof(comp).? << 3),
+ .short, .ushort => 3 + (ty.bitSizeof(comp).? << 3),
+ .int, .uint => 4 + (ty.bitSizeof(comp).? << 3),
+ .long, .ulong => 5 + (ty.bitSizeof(comp).? << 3),
+ .long_long, .ulong_long => 6 + (ty.bitSizeof(comp).? << 3),
+ .int128, .uint128 => 7 + (ty.bitSizeof(comp).? << 3),
+
+ else => unreachable,
+ });
+}
+
+/// Returns true if `a` and `b` are integer types that differ only in sign
+pub fn sameRankDifferentSign(a: Type, b: Type, comp: *const Compilation) bool {
+ if (!a.isInt() or !b.isInt()) return false;
+ if (a.integerRank(comp) != b.integerRank(comp)) return false;
+ return a.isUnsignedInt(comp) != b.isUnsignedInt(comp);
+}
+
+pub fn makeReal(ty: Type) Type {
+ // TODO discards attributed/typeof
+ var base = ty.canonicalize(.standard);
+ switch (base.specifier) {
+ .complex_float, .complex_double, .complex_long_double, .complex_float80, .complex_float128 => {
+ base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 5);
+ return base;
+ },
+ .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128 => {
+ base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 13);
+ return base;
+ },
+ .complex_bit_int => {
+ base.specifier = .bit_int;
+ return base;
+ },
+ else => return ty,
+ }
+}
+
+pub fn makeComplex(ty: Type) Type {
+ // TODO discards attributed/typeof
+ var base = ty.canonicalize(.standard);
+ switch (base.specifier) {
+ .float, .double, .long_double, .float80, .float128 => {
+ base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 5);
+ return base;
+ },
+ .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128 => {
+ base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 13);
+ return base;
+ },
+ .bit_int => {
+ base.specifier = .complex_bit_int;
+ return base;
+ },
+ else => return ty,
+ }
+}
+
+/// Combines types recursively in the order they were parsed, uses `.void` specifier as a sentinel value.
+pub fn combine(inner: *Type, outer: Type) Parser.Error!void {
+ switch (inner.specifier) {
+ .pointer => return inner.data.sub_type.combine(outer),
+ .unspecified_variable_len_array => {
+ try inner.data.sub_type.combine(outer);
+ },
+ .variable_len_array => {
+ try inner.data.expr.ty.combine(outer);
+ },
+ .array, .static_array, .incomplete_array => {
+ try inner.data.array.elem.combine(outer);
+ },
+ .func, .var_args_func, .old_style_func => {
+ try inner.data.func.return_type.combine(outer);
+ },
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ .decayed_typeof_type,
+ .decayed_typeof_expr,
+ => unreachable, // type should not be able to decay before being combined
+ .void => inner.* = outer,
+ else => unreachable,
+ }
+}
+
+pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser.Error!void {
+ switch (ty.specifier) {
+ .pointer => return ty.data.sub_type.validateCombinedType(p, source_tok),
+ .unspecified_variable_len_array,
+ .variable_len_array,
+ .array,
+ .static_array,
+ .incomplete_array,
+ => {
+ const elem_ty = ty.elemType();
+ if (elem_ty.hasIncompleteSize()) {
+ try p.errStr(.array_incomplete_elem, source_tok, try p.typeStr(elem_ty));
+ return error.ParsingFailed;
+ }
+ if (elem_ty.isFunc()) {
+ try p.errTok(.array_func_elem, source_tok);
+ return error.ParsingFailed;
+ }
+ if (elem_ty.specifier == .static_array and elem_ty.isArray()) {
+ try p.errTok(.static_non_outermost_array, source_tok);
+ }
+ if (elem_ty.anyQual() and elem_ty.isArray()) {
+ try p.errTok(.qualifier_non_outermost_array, source_tok);
+ }
+ },
+ .func, .var_args_func, .old_style_func => {
+ const ret_ty = &ty.data.func.return_type;
+ if (ret_ty.isArray()) try p.errTok(.func_cannot_return_array, source_tok);
+ if (ret_ty.isFunc()) try p.errTok(.func_cannot_return_func, source_tok);
+ if (ret_ty.qual.@"const") {
+ try p.errStr(.qual_on_ret_type, source_tok, "const");
+ ret_ty.qual.@"const" = false;
+ }
+ if (ret_ty.qual.@"volatile") {
+ try p.errStr(.qual_on_ret_type, source_tok, "volatile");
+ ret_ty.qual.@"volatile" = false;
+ }
+ if (ret_ty.qual.atomic) {
+ try p.errStr(.qual_on_ret_type, source_tok, "atomic");
+ ret_ty.qual.atomic = false;
+ }
+ if (ret_ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
+ try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value");
+ }
+ },
+ .typeof_type, .decayed_typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok),
+ .typeof_expr, .decayed_typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok),
+ .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok),
+ else => {},
+ }
+}
+
+/// An unfinished Type
+pub const Builder = struct {
+ complex_tok: ?TokenIndex = null,
+ bit_int_tok: ?TokenIndex = null,
+ auto_type_tok: ?TokenIndex = null,
+ typedef: ?struct {
+ tok: TokenIndex,
+ ty: Type,
+ } = null,
+ specifier: Builder.Specifier = .none,
+ qual: Qualifiers.Builder = .{},
+ typeof: ?Type = null,
+ /// When true an error is returned instead of adding a diagnostic message.
+ /// Used for trying to combine typedef types.
+ error_on_invalid: bool = false,
+
+ pub const Specifier = union(enum) {
+ none,
+ void,
+ /// GNU __auto_type extension
+ auto_type,
+ nullptr_t,
+ bool,
+ char,
+ schar,
+ uchar,
+ complex_char,
+ complex_schar,
+ complex_uchar,
+
+ unsigned,
+ signed,
+ short,
+ sshort,
+ ushort,
+ short_int,
+ sshort_int,
+ ushort_int,
+ int,
+ sint,
+ uint,
+ long,
+ slong,
+ ulong,
+ long_int,
+ slong_int,
+ ulong_int,
+ long_long,
+ slong_long,
+ ulong_long,
+ long_long_int,
+ slong_long_int,
+ ulong_long_int,
+ int128,
+ sint128,
+ uint128,
+ complex_unsigned,
+ complex_signed,
+ complex_short,
+ complex_sshort,
+ complex_ushort,
+ complex_short_int,
+ complex_sshort_int,
+ complex_ushort_int,
+ complex_int,
+ complex_sint,
+ complex_uint,
+ complex_long,
+ complex_slong,
+ complex_ulong,
+ complex_long_int,
+ complex_slong_int,
+ complex_ulong_int,
+ complex_long_long,
+ complex_slong_long,
+ complex_ulong_long,
+ complex_long_long_int,
+ complex_slong_long_int,
+ complex_ulong_long_int,
+ complex_int128,
+ complex_sint128,
+ complex_uint128,
+ bit_int: i16,
+ sbit_int: i16,
+ ubit_int: i16,
+ complex_bit_int: i16,
+ complex_sbit_int: i16,
+ complex_ubit_int: i16,
+
+ fp16,
+ float16,
+ float,
+ double,
+ long_double,
+ float80,
+ float128,
+ complex,
+ complex_float,
+ complex_double,
+ complex_long_double,
+ complex_float80,
+ complex_float128,
+
+ pointer: *Type,
+ unspecified_variable_len_array: *Type,
+ decayed_unspecified_variable_len_array: *Type,
+ func: *Func,
+ var_args_func: *Func,
+ old_style_func: *Func,
+ array: *Array,
+ decayed_array: *Array,
+ static_array: *Array,
+ decayed_static_array: *Array,
+ incomplete_array: *Array,
+ decayed_incomplete_array: *Array,
+ vector: *Array,
+ variable_len_array: *Expr,
+ decayed_variable_len_array: *Expr,
+ @"struct": *Record,
+ @"union": *Record,
+ @"enum": *Enum,
+ typeof_type: *Type,
+ decayed_typeof_type: *Type,
+ typeof_expr: *Expr,
+ decayed_typeof_expr: *Expr,
+
+ attributed: *Attributed,
+
+ pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 {
+ return switch (spec) {
+ .none => unreachable,
+ .void => "void",
+ .auto_type => "__auto_type",
+ .nullptr_t => "nullptr_t",
+ .bool => if (langopts.standard.atLeast(.c2x)) "bool" else "_Bool",
+ .char => "char",
+ .schar => "signed char",
+ .uchar => "unsigned char",
+ .unsigned => "unsigned",
+ .signed => "signed",
+ .short => "short",
+ .ushort => "unsigned short",
+ .sshort => "signed short",
+ .short_int => "short int",
+ .sshort_int => "signed short int",
+ .ushort_int => "unsigned short int",
+ .int => "int",
+ .sint => "signed int",
+ .uint => "unsigned int",
+ .long => "long",
+ .slong => "signed long",
+ .ulong => "unsigned long",
+ .long_int => "long int",
+ .slong_int => "signed long int",
+ .ulong_int => "unsigned long int",
+ .long_long => "long long",
+ .slong_long => "signed long long",
+ .ulong_long => "unsigned long long",
+ .long_long_int => "long long int",
+ .slong_long_int => "signed long long int",
+ .ulong_long_int => "unsigned long long int",
+ .int128 => "__int128",
+ .sint128 => "signed __int128",
+ .uint128 => "unsigned __int128",
+ .bit_int => "_BitInt",
+ .sbit_int => "signed _BitInt",
+ .ubit_int => "unsigned _BitInt",
+ .complex_char => "_Complex char",
+ .complex_schar => "_Complex signed char",
+ .complex_uchar => "_Complex unsigned char",
+ .complex_unsigned => "_Complex unsigned",
+ .complex_signed => "_Complex signed",
+ .complex_short => "_Complex short",
+ .complex_ushort => "_Complex unsigned short",
+ .complex_sshort => "_Complex signed short",
+ .complex_short_int => "_Complex short int",
+ .complex_sshort_int => "_Complex signed short int",
+ .complex_ushort_int => "_Complex unsigned short int",
+ .complex_int => "_Complex int",
+ .complex_sint => "_Complex signed int",
+ .complex_uint => "_Complex unsigned int",
+ .complex_long => "_Complex long",
+ .complex_slong => "_Complex signed long",
+ .complex_ulong => "_Complex unsigned long",
+ .complex_long_int => "_Complex long int",
+ .complex_slong_int => "_Complex signed long int",
+ .complex_ulong_int => "_Complex unsigned long int",
+ .complex_long_long => "_Complex long long",
+ .complex_slong_long => "_Complex signed long long",
+ .complex_ulong_long => "_Complex unsigned long long",
+ .complex_long_long_int => "_Complex long long int",
+ .complex_slong_long_int => "_Complex signed long long int",
+ .complex_ulong_long_int => "_Complex unsigned long long int",
+ .complex_int128 => "_Complex __int128",
+ .complex_sint128 => "_Complex signed __int128",
+ .complex_uint128 => "_Complex unsigned __int128",
+ .complex_bit_int => "_Complex _BitInt",
+ .complex_sbit_int => "_Complex signed _BitInt",
+ .complex_ubit_int => "_Complex unsigned _BitInt",
+
+ .fp16 => "__fp16",
+ .float16 => "_Float16",
+ .float => "float",
+ .double => "double",
+ .long_double => "long double",
+ .float80 => "__float80",
+ .float128 => "__float128",
+ .complex => "_Complex",
+ .complex_float => "_Complex float",
+ .complex_double => "_Complex double",
+ .complex_long_double => "_Complex long double",
+ .complex_float80 => "_Complex __float80",
+ .complex_float128 => "_Complex __float128",
+
+ .attributed => |attributed| Builder.fromType(attributed.base).str(langopts),
+
+ else => null,
+ };
+ }
+ };
+
+ pub fn finish(b: Builder, p: *Parser) Parser.Error!Type {
+ var ty: Type = .{ .specifier = undefined };
+ if (b.typedef) |typedef| {
+ ty = typedef.ty;
+ if (ty.isArray()) {
+ var elem = ty.elemType();
+ try b.qual.finish(p, &elem);
+ // TODO this really should be easier
+ switch (ty.specifier) {
+ .array, .static_array, .incomplete_array => {
+ var old = ty.data.array;
+ ty.data.array = try p.arena.create(Array);
+ ty.data.array.* = .{
+ .len = old.len,
+ .elem = elem,
+ };
+ },
+ .variable_len_array, .unspecified_variable_len_array => {
+ var old = ty.data.expr;
+ ty.data.expr = try p.arena.create(Expr);
+ ty.data.expr.* = .{
+ .node = old.node,
+ .ty = elem,
+ };
+ },
+ .typeof_type => {}, // TODO handle
+ .typeof_expr => {}, // TODO handle
+ .attributed => {}, // TODO handle
+ else => unreachable,
+ }
+
+ return ty;
+ }
+ try b.qual.finish(p, &ty);
+ return ty;
+ }
+ switch (b.specifier) {
+ .none => {
+ if (b.typeof) |typeof| {
+ ty = typeof;
+ } else {
+ ty.specifier = .int;
+ try p.err(.missing_type_specifier);
+ }
+ },
+ .void => ty.specifier = .void,
+ .auto_type => ty.specifier = .auto_type,
+ .nullptr_t => unreachable, // nullptr_t can only be accessed via typeof(nullptr)
+ .bool => ty.specifier = .bool,
+ .char => ty.specifier = .char,
+ .schar => ty.specifier = .schar,
+ .uchar => ty.specifier = .uchar,
+ .complex_char => ty.specifier = .complex_char,
+ .complex_schar => ty.specifier = .complex_schar,
+ .complex_uchar => ty.specifier = .complex_uchar,
+
+ .unsigned => ty.specifier = .uint,
+ .signed => ty.specifier = .int,
+ .short_int, .sshort_int, .short, .sshort => ty.specifier = .short,
+ .ushort, .ushort_int => ty.specifier = .ushort,
+ .int, .sint => ty.specifier = .int,
+ .uint => ty.specifier = .uint,
+ .long, .slong, .long_int, .slong_int => ty.specifier = .long,
+ .ulong, .ulong_int => ty.specifier = .ulong,
+ .long_long, .slong_long, .long_long_int, .slong_long_int => ty.specifier = .long_long,
+ .ulong_long, .ulong_long_int => ty.specifier = .ulong_long,
+ .int128, .sint128 => ty.specifier = .int128,
+ .uint128 => ty.specifier = .uint128,
+ .complex_unsigned => ty.specifier = .complex_uint,
+ .complex_signed => ty.specifier = .complex_int,
+ .complex_short_int, .complex_sshort_int, .complex_short, .complex_sshort => ty.specifier = .complex_short,
+ .complex_ushort, .complex_ushort_int => ty.specifier = .complex_ushort,
+ .complex_int, .complex_sint => ty.specifier = .complex_int,
+ .complex_uint => ty.specifier = .complex_uint,
+ .complex_long, .complex_slong, .complex_long_int, .complex_slong_int => ty.specifier = .complex_long,
+ .complex_ulong, .complex_ulong_int => ty.specifier = .complex_ulong,
+ .complex_long_long, .complex_slong_long, .complex_long_long_int, .complex_slong_long_int => ty.specifier = .complex_long_long,
+ .complex_ulong_long, .complex_ulong_long_int => ty.specifier = .complex_ulong_long,
+ .complex_int128, .complex_sint128 => ty.specifier = .complex_int128,
+ .complex_uint128 => ty.specifier = .complex_uint128,
+ .bit_int, .sbit_int, .ubit_int, .complex_bit_int, .complex_ubit_int, .complex_sbit_int => |bits| {
+ const unsigned = b.specifier == .ubit_int or b.specifier == .complex_ubit_int;
+ if (unsigned) {
+ if (bits < 1) {
+ try p.errStr(.unsigned_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
+ return error.ParsingFailed;
+ }
+ } else {
+ if (bits < 2) {
+ try p.errStr(.signed_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
+ return error.ParsingFailed;
+ }
+ }
+ if (bits > Compilation.bit_int_max_bits) {
+ try p.errStr(.bit_int_too_big, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
+ return error.ParsingFailed;
+ }
+ ty.specifier = if (b.complex_tok != null) .complex_bit_int else .bit_int;
+ ty.data = .{ .int = .{
+ .signedness = if (unsigned) .unsigned else .signed,
+ .bits = @intCast(bits),
+ } };
+ },
+
+ .fp16 => ty.specifier = .fp16,
+ .float16 => ty.specifier = .float16,
+ .float => ty.specifier = .float,
+ .double => ty.specifier = .double,
+ .long_double => ty.specifier = .long_double,
+ .float80 => ty.specifier = .float80,
+ .float128 => ty.specifier = .float128,
+ .complex_float => ty.specifier = .complex_float,
+ .complex_double => ty.specifier = .complex_double,
+ .complex_long_double => ty.specifier = .complex_long_double,
+ .complex_float80 => ty.specifier = .complex_float80,
+ .complex_float128 => ty.specifier = .complex_float128,
+ .complex => {
+ try p.errTok(.plain_complex, p.tok_i - 1);
+ ty.specifier = .complex_double;
+ },
+
+ .pointer => |data| {
+ ty.specifier = .pointer;
+ ty.data = .{ .sub_type = data };
+ },
+ .unspecified_variable_len_array => |data| {
+ ty.specifier = .unspecified_variable_len_array;
+ ty.data = .{ .sub_type = data };
+ },
+ .decayed_unspecified_variable_len_array => |data| {
+ ty.specifier = .decayed_unspecified_variable_len_array;
+ ty.data = .{ .sub_type = data };
+ },
+ .func => |data| {
+ ty.specifier = .func;
+ ty.data = .{ .func = data };
+ },
+ .var_args_func => |data| {
+ ty.specifier = .var_args_func;
+ ty.data = .{ .func = data };
+ },
+ .old_style_func => |data| {
+ ty.specifier = .old_style_func;
+ ty.data = .{ .func = data };
+ },
+ .array => |data| {
+ ty.specifier = .array;
+ ty.data = .{ .array = data };
+ },
+ .decayed_array => |data| {
+ ty.specifier = .decayed_array;
+ ty.data = .{ .array = data };
+ },
+ .static_array => |data| {
+ ty.specifier = .static_array;
+ ty.data = .{ .array = data };
+ },
+ .decayed_static_array => |data| {
+ ty.specifier = .decayed_static_array;
+ ty.data = .{ .array = data };
+ },
+ .incomplete_array => |data| {
+ ty.specifier = .incomplete_array;
+ ty.data = .{ .array = data };
+ },
+ .decayed_incomplete_array => |data| {
+ ty.specifier = .decayed_incomplete_array;
+ ty.data = .{ .array = data };
+ },
+ .vector => |data| {
+ ty.specifier = .vector;
+ ty.data = .{ .array = data };
+ },
+ .variable_len_array => |data| {
+ ty.specifier = .variable_len_array;
+ ty.data = .{ .expr = data };
+ },
+ .decayed_variable_len_array => |data| {
+ ty.specifier = .decayed_variable_len_array;
+ ty.data = .{ .expr = data };
+ },
+ .@"struct" => |data| {
+ ty.specifier = .@"struct";
+ ty.data = .{ .record = data };
+ },
+ .@"union" => |data| {
+ ty.specifier = .@"union";
+ ty.data = .{ .record = data };
+ },
+ .@"enum" => |data| {
+ ty.specifier = .@"enum";
+ ty.data = .{ .@"enum" = data };
+ },
+ .typeof_type => |data| {
+ ty.specifier = .typeof_type;
+ ty.data = .{ .sub_type = data };
+ },
+ .decayed_typeof_type => |data| {
+ ty.specifier = .decayed_typeof_type;
+ ty.data = .{ .sub_type = data };
+ },
+ .typeof_expr => |data| {
+ ty.specifier = .typeof_expr;
+ ty.data = .{ .expr = data };
+ },
+ .decayed_typeof_expr => |data| {
+ ty.specifier = .decayed_typeof_expr;
+ ty.data = .{ .expr = data };
+ },
+ .attributed => |data| {
+ ty.specifier = .attributed;
+ ty.data = .{ .attributed = data };
+ },
+ }
+ if (!ty.isReal() and ty.isInt()) {
+ if (b.complex_tok) |tok| try p.errTok(.complex_int, tok);
+ }
+ try b.qual.finish(p, &ty);
+ return ty;
+ }
+
+ fn cannotCombine(b: Builder, p: *Parser, source_tok: TokenIndex) !void {
+ if (b.error_on_invalid) return error.CannotCombine;
+ const ty_str = b.specifier.str(p.comp.langopts) orelse try p.typeStr(try b.finish(p));
+ try p.errExtra(.cannot_combine_spec, source_tok, .{ .str = ty_str });
+ if (b.typedef) |some| try p.errStr(.spec_from_typedef, some.tok, try p.typeStr(some.ty));
+ }
+
+ fn duplicateSpec(b: *Builder, p: *Parser, source_tok: TokenIndex, spec: []const u8) !void {
+ if (b.error_on_invalid) return error.CannotCombine;
+ if (p.comp.langopts.emulate != .clang) return b.cannotCombine(p, source_tok);
+ try p.errStr(.duplicate_decl_spec, p.tok_i, spec);
+ }
+
+ pub fn combineFromTypeof(b: *Builder, p: *Parser, new: Type, source_tok: TokenIndex) Compilation.Error!void {
+ if (b.typeof != null) return p.errStr(.cannot_combine_spec, source_tok, "typeof");
+ if (b.specifier != .none) return p.errStr(.invalid_typeof, source_tok, @tagName(b.specifier));
+ const inner = switch (new.specifier) {
+ .typeof_type => new.data.sub_type.*,
+ .typeof_expr => new.data.expr.ty,
+ .nullptr_t => new, // typeof(nullptr) is special-cased to be an unwrapped typeof-expr
+ else => unreachable,
+ };
+
+ b.typeof = switch (inner.specifier) {
+ .attributed => inner.data.attributed.base,
+ else => new,
+ };
+ }
+
+ /// Try to combine type from typedef, returns true if successful.
+ pub fn combineTypedef(b: *Builder, p: *Parser, typedef_ty: Type, name_tok: TokenIndex) bool {
+ b.error_on_invalid = true;
+ defer b.error_on_invalid = false;
+
+ const new_spec = fromType(typedef_ty);
+ b.combineExtra(p, new_spec, 0) catch |err| switch (err) {
+ error.FatalError => unreachable, // we do not add any diagnostics
+ error.OutOfMemory => unreachable, // we do not add any diagnostics
+ error.ParsingFailed => unreachable, // we do not add any diagnostics
+ error.CannotCombine => return false,
+ };
+ b.typedef = .{ .tok = name_tok, .ty = typedef_ty };
+ return true;
+ }
+
+ pub fn combine(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
+ b.combineExtra(p, new, source_tok) catch |err| switch (err) {
+ error.CannotCombine => unreachable,
+ else => |e| return e,
+ };
+ }
+
+ fn combineExtra(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
+ if (b.typeof != null) {
+ if (b.error_on_invalid) return error.CannotCombine;
+ try p.errStr(.invalid_typeof, source_tok, @tagName(new));
+ }
+
+ switch (new) {
+ .complex => b.complex_tok = source_tok,
+ .bit_int => b.bit_int_tok = source_tok,
+ .auto_type => b.auto_type_tok = source_tok,
+ else => {},
+ }
+
+ if (new == .int128 and !target_util.hasInt128(p.comp.target)) {
+ try p.errStr(.type_not_supported_on_target, source_tok, "__int128");
+ }
+
+ switch (new) {
+ else => switch (b.specifier) {
+ .none => b.specifier = new,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .signed => b.specifier = switch (b.specifier) {
+ .none => .signed,
+ .char => .schar,
+ .short => .sshort,
+ .short_int => .sshort_int,
+ .int => .sint,
+ .long => .slong,
+ .long_int => .slong_int,
+ .long_long => .slong_long,
+ .long_long_int => .slong_long_int,
+ .int128 => .sint128,
+ .bit_int => |bits| .{ .sbit_int = bits },
+ .complex => .complex_signed,
+ .complex_char => .complex_schar,
+ .complex_short => .complex_sshort,
+ .complex_short_int => .complex_sshort_int,
+ .complex_int => .complex_sint,
+ .complex_long => .complex_slong,
+ .complex_long_int => .complex_slong_int,
+ .complex_long_long => .complex_slong_long,
+ .complex_long_long_int => .complex_slong_long_int,
+ .complex_int128 => .complex_sint128,
+ .complex_bit_int => |bits| .{ .complex_sbit_int = bits },
+ .signed,
+ .sshort,
+ .sshort_int,
+ .sint,
+ .slong,
+ .slong_int,
+ .slong_long,
+ .slong_long_int,
+ .sint128,
+ .sbit_int,
+ .complex_schar,
+ .complex_signed,
+ .complex_sshort,
+ .complex_sshort_int,
+ .complex_sint,
+ .complex_slong,
+ .complex_slong_int,
+ .complex_slong_long,
+ .complex_slong_long_int,
+ .complex_sint128,
+ .complex_sbit_int,
+ => return b.duplicateSpec(p, source_tok, "signed"),
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .unsigned => b.specifier = switch (b.specifier) {
+ .none => .unsigned,
+ .char => .uchar,
+ .short => .ushort,
+ .short_int => .ushort_int,
+ .int => .uint,
+ .long => .ulong,
+ .long_int => .ulong_int,
+ .long_long => .ulong_long,
+ .long_long_int => .ulong_long_int,
+ .int128 => .uint128,
+ .bit_int => |bits| .{ .ubit_int = bits },
+ .complex => .complex_unsigned,
+ .complex_char => .complex_uchar,
+ .complex_short => .complex_ushort,
+ .complex_short_int => .complex_ushort_int,
+ .complex_int => .complex_uint,
+ .complex_long => .complex_ulong,
+ .complex_long_int => .complex_ulong_int,
+ .complex_long_long => .complex_ulong_long,
+ .complex_long_long_int => .complex_ulong_long_int,
+ .complex_int128 => .complex_uint128,
+ .complex_bit_int => |bits| .{ .complex_ubit_int = bits },
+ .unsigned,
+ .ushort,
+ .ushort_int,
+ .uint,
+ .ulong,
+ .ulong_int,
+ .ulong_long,
+ .ulong_long_int,
+ .uint128,
+ .ubit_int,
+ .complex_uchar,
+ .complex_unsigned,
+ .complex_ushort,
+ .complex_ushort_int,
+ .complex_uint,
+ .complex_ulong,
+ .complex_ulong_int,
+ .complex_ulong_long,
+ .complex_ulong_long_int,
+ .complex_uint128,
+ .complex_ubit_int,
+ => return b.duplicateSpec(p, source_tok, "unsigned"),
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .char => b.specifier = switch (b.specifier) {
+ .none => .char,
+ .unsigned => .uchar,
+ .signed => .schar,
+ .complex => .complex_char,
+ .complex_signed => .complex_schar,
+ .complex_unsigned => .complex_uchar,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .short => b.specifier = switch (b.specifier) {
+ .none => .short,
+ .unsigned => .ushort,
+ .signed => .sshort,
+ .int => .short_int,
+ .sint => .sshort_int,
+ .uint => .ushort_int,
+ .complex => .complex_short,
+ .complex_signed => .complex_sshort,
+ .complex_unsigned => .complex_ushort,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .int => b.specifier = switch (b.specifier) {
+ .none => .int,
+ .signed => .sint,
+ .unsigned => .uint,
+ .short => .short_int,
+ .sshort => .sshort_int,
+ .ushort => .ushort_int,
+ .long => .long_int,
+ .slong => .slong_int,
+ .ulong => .ulong_int,
+ .long_long => .long_long_int,
+ .slong_long => .slong_long_int,
+ .ulong_long => .ulong_long_int,
+ .complex => .complex_int,
+ .complex_signed => .complex_sint,
+ .complex_unsigned => .complex_uint,
+ .complex_short => .complex_short_int,
+ .complex_sshort => .complex_sshort_int,
+ .complex_ushort => .complex_ushort_int,
+ .complex_long => .complex_long_int,
+ .complex_slong => .complex_slong_int,
+ .complex_ulong => .complex_ulong_int,
+ .complex_long_long => .complex_long_long_int,
+ .complex_slong_long => .complex_slong_long_int,
+ .complex_ulong_long => .complex_ulong_long_int,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .long => b.specifier = switch (b.specifier) {
+ .none => .long,
+ .long => .long_long,
+ .unsigned => .ulong,
+ .signed => .long,
+ .int => .long_int,
+ .sint => .slong_int,
+ .ulong => .ulong_long,
+ .complex => .complex_long,
+ .complex_signed => .complex_slong,
+ .complex_unsigned => .complex_ulong,
+ .complex_long => .complex_long_long,
+ .complex_slong => .complex_slong_long,
+ .complex_ulong => .complex_ulong_long,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .int128 => b.specifier = switch (b.specifier) {
+ .none => .int128,
+ .unsigned => .uint128,
+ .signed => .sint128,
+ .complex => .complex_int128,
+ .complex_signed => .complex_sint128,
+ .complex_unsigned => .complex_uint128,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .bit_int => b.specifier = switch (b.specifier) {
+ .none => .{ .bit_int = new.bit_int },
+ .unsigned => .{ .ubit_int = new.bit_int },
+ .signed => .{ .sbit_int = new.bit_int },
+ .complex => .{ .complex_bit_int = new.bit_int },
+ .complex_signed => .{ .complex_sbit_int = new.bit_int },
+ .complex_unsigned => .{ .complex_ubit_int = new.bit_int },
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .auto_type => b.specifier = switch (b.specifier) {
+ .none => .auto_type,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .fp16 => b.specifier = switch (b.specifier) {
+ .none => .fp16,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .float16 => b.specifier = switch (b.specifier) {
+ .none => .float16,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .float => b.specifier = switch (b.specifier) {
+ .none => .float,
+ .complex => .complex_float,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .double => b.specifier = switch (b.specifier) {
+ .none => .double,
+ .long => .long_double,
+ .complex_long => .complex_long_double,
+ .complex => .complex_double,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .float80 => b.specifier = switch (b.specifier) {
+ .none => .float80,
+ .complex => .complex_float80,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .float128 => b.specifier = switch (b.specifier) {
+ .none => .float128,
+ .complex => .complex_float128,
+ else => return b.cannotCombine(p, source_tok),
+ },
+ .complex => b.specifier = switch (b.specifier) {
+ .none => .complex,
+ .float => .complex_float,
+ .double => .complex_double,
+ .long_double => .complex_long_double,
+ .float80 => .complex_float80,
+ .float128 => .complex_float128,
+ .char => .complex_char,
+ .schar => .complex_schar,
+ .uchar => .complex_uchar,
+ .unsigned => .complex_unsigned,
+ .signed => .complex_signed,
+ .short => .complex_short,
+ .sshort => .complex_sshort,
+ .ushort => .complex_ushort,
+ .short_int => .complex_short_int,
+ .sshort_int => .complex_sshort_int,
+ .ushort_int => .complex_ushort_int,
+ .int => .complex_int,
+ .sint => .complex_sint,
+ .uint => .complex_uint,
+ .long => .complex_long,
+ .slong => .complex_slong,
+ .ulong => .complex_ulong,
+ .long_int => .complex_long_int,
+ .slong_int => .complex_slong_int,
+ .ulong_int => .complex_ulong_int,
+ .long_long => .complex_long_long,
+ .slong_long => .complex_slong_long,
+ .ulong_long => .complex_ulong_long,
+ .long_long_int => .complex_long_long_int,
+ .slong_long_int => .complex_slong_long_int,
+ .ulong_long_int => .complex_ulong_long_int,
+ .int128 => .complex_int128,
+ .sint128 => .complex_sint128,
+ .uint128 => .complex_uint128,
+ .bit_int => |bits| .{ .complex_bit_int = bits },
+ .sbit_int => |bits| .{ .complex_sbit_int = bits },
+ .ubit_int => |bits| .{ .complex_ubit_int = bits },
+ .complex,
+ .complex_float,
+ .complex_double,
+ .complex_long_double,
+ .complex_float80,
+ .complex_float128,
+ .complex_char,
+ .complex_schar,
+ .complex_uchar,
+ .complex_unsigned,
+ .complex_signed,
+ .complex_short,
+ .complex_sshort,
+ .complex_ushort,
+ .complex_short_int,
+ .complex_sshort_int,
+ .complex_ushort_int,
+ .complex_int,
+ .complex_sint,
+ .complex_uint,
+ .complex_long,
+ .complex_slong,
+ .complex_ulong,
+ .complex_long_int,
+ .complex_slong_int,
+ .complex_ulong_int,
+ .complex_long_long,
+ .complex_slong_long,
+ .complex_ulong_long,
+ .complex_long_long_int,
+ .complex_slong_long_int,
+ .complex_ulong_long_int,
+ .complex_int128,
+ .complex_sint128,
+ .complex_uint128,
+ .complex_bit_int,
+ .complex_sbit_int,
+ .complex_ubit_int,
+ => return b.duplicateSpec(p, source_tok, "_Complex"),
+ else => return b.cannotCombine(p, source_tok),
+ },
+ }
+ }
+
+ pub fn fromType(ty: Type) Builder.Specifier {
+ return switch (ty.specifier) {
+ .void => .void,
+ .auto_type => .auto_type,
+ .nullptr_t => .nullptr_t,
+ .bool => .bool,
+ .char => .char,
+ .schar => .schar,
+ .uchar => .uchar,
+ .short => .short,
+ .ushort => .ushort,
+ .int => .int,
+ .uint => .uint,
+ .long => .long,
+ .ulong => .ulong,
+ .long_long => .long_long,
+ .ulong_long => .ulong_long,
+ .int128 => .int128,
+ .uint128 => .uint128,
+ .bit_int => if (ty.data.int.signedness == .unsigned) {
+ return .{ .ubit_int = ty.data.int.bits };
+ } else {
+ return .{ .bit_int = ty.data.int.bits };
+ },
+ .complex_char => .complex_char,
+ .complex_schar => .complex_schar,
+ .complex_uchar => .complex_uchar,
+ .complex_short => .complex_short,
+ .complex_ushort => .complex_ushort,
+ .complex_int => .complex_int,
+ .complex_uint => .complex_uint,
+ .complex_long => .complex_long,
+ .complex_ulong => .complex_ulong,
+ .complex_long_long => .complex_long_long,
+ .complex_ulong_long => .complex_ulong_long,
+ .complex_int128 => .complex_int128,
+ .complex_uint128 => .complex_uint128,
+ .complex_bit_int => if (ty.data.int.signedness == .unsigned) {
+ return .{ .complex_ubit_int = ty.data.int.bits };
+ } else {
+ return .{ .complex_bit_int = ty.data.int.bits };
+ },
+ .fp16 => .fp16,
+ .float16 => .float16,
+ .float => .float,
+ .double => .double,
+ .float80 => .float80,
+ .float128 => .float128,
+ .long_double => .long_double,
+ .complex_float => .complex_float,
+ .complex_double => .complex_double,
+ .complex_long_double => .complex_long_double,
+ .complex_float80 => .complex_float80,
+ .complex_float128 => .complex_float128,
+
+ .pointer => .{ .pointer = ty.data.sub_type },
+ .unspecified_variable_len_array => .{ .unspecified_variable_len_array = ty.data.sub_type },
+ .decayed_unspecified_variable_len_array => .{ .decayed_unspecified_variable_len_array = ty.data.sub_type },
+ .func => .{ .func = ty.data.func },
+ .var_args_func => .{ .var_args_func = ty.data.func },
+ .old_style_func => .{ .old_style_func = ty.data.func },
+ .array => .{ .array = ty.data.array },
+ .decayed_array => .{ .decayed_array = ty.data.array },
+ .static_array => .{ .static_array = ty.data.array },
+ .decayed_static_array => .{ .decayed_static_array = ty.data.array },
+ .incomplete_array => .{ .incomplete_array = ty.data.array },
+ .decayed_incomplete_array => .{ .decayed_incomplete_array = ty.data.array },
+ .vector => .{ .vector = ty.data.array },
+ .variable_len_array => .{ .variable_len_array = ty.data.expr },
+ .decayed_variable_len_array => .{ .decayed_variable_len_array = ty.data.expr },
+ .@"struct" => .{ .@"struct" = ty.data.record },
+ .@"union" => .{ .@"union" = ty.data.record },
+ .@"enum" => .{ .@"enum" = ty.data.@"enum" },
+
+ .typeof_type => .{ .typeof_type = ty.data.sub_type },
+ .decayed_typeof_type => .{ .decayed_typeof_type = ty.data.sub_type },
+ .typeof_expr => .{ .typeof_expr = ty.data.expr },
+ .decayed_typeof_expr => .{ .decayed_typeof_expr = ty.data.expr },
+
+ .attributed => .{ .attributed = ty.data.attributed },
+ else => unreachable,
+ };
+ }
+};
+
+pub fn getAttribute(ty: Type, comptime tag: Attribute.Tag) ?Attribute.ArgumentsForTag(tag) {
+ switch (ty.specifier) {
+ .typeof_type => return ty.data.sub_type.getAttribute(tag),
+ .typeof_expr => return ty.data.expr.ty.getAttribute(tag),
+ .attributed => {
+ for (ty.data.attributed.attributes) |attribute| {
+ if (attribute.tag == tag) return @field(attribute.args, @tagName(tag));
+ }
+ return null;
+ },
+ else => return null,
+ }
+}
+
+pub fn hasAttribute(ty: Type, tag: Attribute.Tag) bool {
+ for (ty.getAttributes()) |attr| {
+ if (attr.tag == tag) return true;
+ }
+ return false;
+}
+
+/// printf format modifier
+pub fn formatModifier(ty: Type) []const u8 {
+ return switch (ty.specifier) {
+ .schar, .uchar => "hh",
+ .short, .ushort => "h",
+ .int, .uint => "",
+ .long, .ulong => "l",
+ .long_long, .ulong_long => "ll",
+ else => unreachable,
+ };
+}
+
+/// Suffix for integer values of this type
+pub fn intValueSuffix(ty: Type, comp: *const Compilation) []const u8 {
+ return switch (ty.specifier) {
+ .schar, .short, .int => "",
+ .long => "L",
+ .long_long => "LL",
+ .uchar, .char => {
+ if (ty.specifier == .char and comp.getCharSignedness() == .signed) return "";
+ // Only 8-bit char supported currently;
+ // TODO: handle platforms with 16-bit int + 16-bit char
+ std.debug.assert(ty.sizeof(comp).? == 1);
+ return "";
+ },
+ .ushort => {
+ if (ty.sizeof(comp).? < int.sizeof(comp).?) {
+ return "";
+ }
+ return "U";
+ },
+ .uint => "U",
+ .ulong => "UL",
+ .ulong_long => "ULL",
+ else => unreachable, // not integer
+ };
+}
+
+/// Print type in C style
+pub fn print(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+ _ = try ty.printPrologue(mapper, langopts, w);
+ try ty.printEpilogue(mapper, langopts, w);
+}
+
+pub fn printNamed(ty: Type, name: []const u8, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+ const simple = try ty.printPrologue(mapper, langopts, w);
+ if (simple) try w.writeByte(' ');
+ try w.writeAll(name);
+ try ty.printEpilogue(mapper, langopts, w);
+}
+
+const StringGetter = fn (TokenIndex) []const u8;
+
+/// return true if `ty` is simple
+fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!bool {
+ if (ty.qual.atomic) {
+ var non_atomic_ty = ty;
+ non_atomic_ty.qual.atomic = false;
+ try w.writeAll("_Atomic(");
+ try non_atomic_ty.print(mapper, langopts, w);
+ try w.writeAll(")");
+ return true;
+ }
+ switch (ty.specifier) {
+ .pointer,
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ .decayed_typeof_type,
+ .decayed_typeof_expr,
+ => {
+ const elem_ty = ty.elemType();
+ const simple = try elem_ty.printPrologue(mapper, langopts, w);
+ if (simple) try w.writeByte(' ');
+ if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('(');
+ try w.writeByte('*');
+ try ty.qual.dump(w);
+ return false;
+ },
+ .func, .var_args_func, .old_style_func => {
+ const ret_ty = ty.data.func.return_type;
+ const simple = try ret_ty.printPrologue(mapper, langopts, w);
+ if (simple) try w.writeByte(' ');
+ return false;
+ },
+ .array, .static_array, .incomplete_array, .unspecified_variable_len_array, .variable_len_array => {
+ const elem_ty = ty.elemType();
+ const simple = try elem_ty.printPrologue(mapper, langopts, w);
+ if (simple) try w.writeByte(' ');
+ return false;
+ },
+ .typeof_type, .typeof_expr => {
+ const actual = ty.canonicalize(.standard);
+ return actual.printPrologue(mapper, langopts, w);
+ },
+ .attributed => {
+ const actual = ty.canonicalize(.standard);
+ return actual.printPrologue(mapper, langopts, w);
+ },
+ else => {},
+ }
+ try ty.qual.dump(w);
+
+ switch (ty.specifier) {
+ .@"enum" => if (ty.data.@"enum".fixed) {
+ try w.print("enum {s}: ", .{mapper.lookup(ty.data.@"enum".name)});
+ try ty.data.@"enum".tag_ty.dump(mapper, langopts, w);
+ } else {
+ try w.print("enum {s}", .{mapper.lookup(ty.data.@"enum".name)});
+ },
+ .@"struct" => try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)}),
+ .@"union" => try w.print("union {s}", .{mapper.lookup(ty.data.record.name)}),
+ .vector => {
+ const len = ty.data.array.len;
+ const elem_ty = ty.data.array.elem;
+ try w.print("__attribute__((__vector_size__({d} * sizeof(", .{len});
+ _ = try elem_ty.printPrologue(mapper, langopts, w);
+ try w.writeAll(")))) ");
+ _ = try elem_ty.printPrologue(mapper, langopts, w);
+ try w.print(" (vector of {d} '", .{len});
+ _ = try elem_ty.printPrologue(mapper, langopts, w);
+ try w.writeAll("' values)");
+ },
+ else => try w.writeAll(Builder.fromType(ty).str(langopts).?),
+ }
+ return true;
+}
+
+fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+ if (ty.qual.atomic) return;
+ switch (ty.specifier) {
+ .pointer,
+ .decayed_array,
+ .decayed_static_array,
+ .decayed_incomplete_array,
+ .decayed_variable_len_array,
+ .decayed_unspecified_variable_len_array,
+ .decayed_typeof_type,
+ .decayed_typeof_expr,
+ => {
+ const elem_ty = ty.elemType();
+ if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')');
+ try elem_ty.printEpilogue(mapper, langopts, w);
+ },
+ .func, .var_args_func, .old_style_func => {
+ try w.writeByte('(');
+ for (ty.data.func.params, 0..) |param, i| {
+ if (i != 0) try w.writeAll(", ");
+ _ = try param.ty.printPrologue(mapper, langopts, w);
+ try param.ty.printEpilogue(mapper, langopts, w);
+ }
+ if (ty.specifier != .func) {
+ if (ty.data.func.params.len != 0) try w.writeAll(", ");
+ try w.writeAll("...");
+ } else if (ty.data.func.params.len == 0) {
+ try w.writeAll("void");
+ }
+ try w.writeByte(')');
+ try ty.data.func.return_type.printEpilogue(mapper, langopts, w);
+ },
+ .array, .static_array => {
+ try w.writeByte('[');
+ if (ty.specifier == .static_array) try w.writeAll("static ");
+ try ty.qual.dump(w);
+ try w.print("{d}]", .{ty.data.array.len});
+ try ty.data.array.elem.printEpilogue(mapper, langopts, w);
+ },
+ .incomplete_array => {
+ try w.writeByte('[');
+ try ty.qual.dump(w);
+ try w.writeByte(']');
+ try ty.data.array.elem.printEpilogue(mapper, langopts, w);
+ },
+ .unspecified_variable_len_array => {
+ try w.writeByte('[');
+ try ty.qual.dump(w);
+ try w.writeAll("*]");
+ try ty.data.sub_type.printEpilogue(mapper, langopts, w);
+ },
+ .variable_len_array => {
+ try w.writeByte('[');
+ try ty.qual.dump(w);
+ try w.writeAll("<expr>]");
+ try ty.data.expr.ty.printEpilogue(mapper, langopts, w);
+ },
+ .typeof_type, .typeof_expr => {
+ const actual = ty.canonicalize(.standard);
+ try actual.printEpilogue(mapper, langopts, w);
+ },
+ .attributed => {
+ const actual = ty.canonicalize(.standard);
+ try actual.printEpilogue(mapper, langopts, w);
+ },
+ else => {},
+ }
+}
+
+/// Useful for debugging, too noisy to be enabled by default.
+const dump_detailed_containers = false;
+
+// Print as Zig types since those are actually readable
+pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+ try ty.qual.dump(w);
+ switch (ty.specifier) {
+ .invalid => try w.writeAll("invalid"),
+ .pointer => {
+ try w.writeAll("*");
+ try ty.data.sub_type.dump(mapper, langopts, w);
+ },
+ .func, .var_args_func, .old_style_func => {
+ try w.writeAll("fn (");
+ for (ty.data.func.params, 0..) |param, i| {
+ if (i != 0) try w.writeAll(", ");
+ if (param.name != .empty) try w.print("{s}: ", .{mapper.lookup(param.name)});
+ try param.ty.dump(mapper, langopts, w);
+ }
+ if (ty.specifier != .func) {
+ if (ty.data.func.params.len != 0) try w.writeAll(", ");
+ try w.writeAll("...");
+ }
+ try w.writeAll(") ");
+ try ty.data.func.return_type.dump(mapper, langopts, w);
+ },
+ .array, .static_array, .decayed_array, .decayed_static_array => {
+ if (ty.specifier == .decayed_array or ty.specifier == .decayed_static_array) try w.writeByte('d');
+ try w.writeByte('[');
+ if (ty.specifier == .static_array or ty.specifier == .decayed_static_array) try w.writeAll("static ");
+ try w.print("{d}]", .{ty.data.array.len});
+ try ty.data.array.elem.dump(mapper, langopts, w);
+ },
+ .vector => {
+ try w.print("vector({d}, ", .{ty.data.array.len});
+ try ty.data.array.elem.dump(mapper, langopts, w);
+ try w.writeAll(")");
+ },
+ .incomplete_array, .decayed_incomplete_array => {
+ if (ty.specifier == .decayed_incomplete_array) try w.writeByte('d');
+ try w.writeAll("[]");
+ try ty.data.array.elem.dump(mapper, langopts, w);
+ },
+ .@"enum" => {
+ const enum_ty = ty.data.@"enum";
+ if (enum_ty.isIncomplete() and !enum_ty.fixed) {
+ try w.print("enum {s}", .{mapper.lookup(enum_ty.name)});
+ } else {
+ try w.print("enum {s}: ", .{mapper.lookup(enum_ty.name)});
+ try enum_ty.tag_ty.dump(mapper, langopts, w);
+ }
+ if (dump_detailed_containers) try dumpEnum(enum_ty, mapper, w);
+ },
+ .@"struct" => {
+ try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)});
+ if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
+ },
+ .@"union" => {
+ try w.print("union {s}", .{mapper.lookup(ty.data.record.name)});
+ if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
+ },
+ .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => {
+ if (ty.specifier == .decayed_unspecified_variable_len_array) try w.writeByte('d');
+ try w.writeAll("[*]");
+ try ty.data.sub_type.dump(mapper, langopts, w);
+ },
+ .variable_len_array, .decayed_variable_len_array => {
+ if (ty.specifier == .decayed_variable_len_array) try w.writeByte('d');
+ try w.writeAll("[<expr>]");
+ try ty.data.expr.ty.dump(mapper, langopts, w);
+ },
+ .typeof_type, .decayed_typeof_type => {
+ try w.writeAll("typeof(");
+ try ty.data.sub_type.dump(mapper, langopts, w);
+ try w.writeAll(")");
+ },
+ .typeof_expr, .decayed_typeof_expr => {
+ try w.writeAll("typeof(<expr>: ");
+ try ty.data.expr.ty.dump(mapper, langopts, w);
+ try w.writeAll(")");
+ },
+ .attributed => {
+ try w.writeAll("attributed(");
+ try ty.data.attributed.base.dump(mapper, langopts, w);
+ try w.writeAll(")");
+ },
+ else => {
+ try w.writeAll(Builder.fromType(ty).str(langopts).?);
+ if (ty.specifier == .bit_int or ty.specifier == .complex_bit_int) {
+ try w.print("({d})", .{ty.data.int.bits});
+ }
+ },
+ }
+}
+
+fn dumpEnum(@"enum": *Enum, mapper: StringInterner.TypeMapper, w: anytype) @TypeOf(w).Error!void {
+ try w.writeAll(" {");
+ for (@"enum".fields) |field| {
+ try w.print(" {s} = {d},", .{ mapper.lookup(field.name), field.value });
+ }
+ try w.writeAll(" }");
+}
+
+fn dumpRecord(record: *Record, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+ try w.writeAll(" {");
+ for (record.fields) |field| {
+ try w.writeByte(' ');
+ try field.ty.dump(mapper, langopts, w);
+ try w.print(" {s}: {d};", .{ mapper.lookup(field.name), field.bit_width });
+ }
+ try w.writeAll(" }");
+}
deps/aro/unicode.zig
@@ -0,0 +1,41 @@
+//! Copied from https://github.com/ziglang/zig/blob/6f0807f50f4e946bb850e746beaa5d6556cf7750/lib/std/unicode.zig
+//! with all safety checks removed. These functions must only be called with known-good buffers that have already
+//! been validated as being legitimate UTF8-encoded data, otherwise undefined behavior will occur.
+
+pub fn utf8ByteSequenceLength_unsafe(first_byte: u8) u3 {
+ return switch (first_byte) {
+ 0b0000_0000...0b0111_1111 => 1,
+ 0b1100_0000...0b1101_1111 => 2,
+ 0b1110_0000...0b1110_1111 => 3,
+ 0b1111_0000...0b1111_0111 => 4,
+ else => unreachable,
+ };
+}
+
+pub fn utf8Decode2_unsafe(bytes: []const u8) u21 {
+ var value: u21 = bytes[0] & 0b00011111;
+ value <<= 6;
+ return value | (bytes[1] & 0b00111111);
+}
+
+pub fn utf8Decode3_unsafe(bytes: []const u8) u21 {
+ var value: u21 = bytes[0] & 0b00001111;
+
+ value <<= 6;
+ value |= bytes[1] & 0b00111111;
+
+ value <<= 6;
+ return value | (bytes[2] & 0b00111111);
+}
+
+pub fn utf8Decode4_unsafe(bytes: []const u8) u21 {
+ var value: u21 = bytes[0] & 0b00000111;
+ value <<= 6;
+ value |= bytes[1] & 0b00111111;
+
+ value <<= 6;
+ value |= bytes[2] & 0b00111111;
+
+ value <<= 6;
+ return value | (bytes[3] & 0b00111111);
+}
deps/aro/util.zig
@@ -0,0 +1,83 @@
+const std = @import("std");
+const mem = std.mem;
+const builtin = @import("builtin");
+const is_windows = builtin.os.tag == .windows;
+
+pub const Color = enum {
+ reset,
+ red,
+ green,
+ blue,
+ cyan,
+ purple,
+ yellow,
+ white,
+};
+
+pub fn fileSupportsColor(file: std.fs.File) bool {
+ return file.supportsAnsiEscapeCodes() or (is_windows and file.isTty());
+}
+
+pub fn setColor(color: Color, w: anytype) void {
+ if (is_windows) {
+ const stderr_file = std.io.getStdErr();
+ if (!stderr_file.isTty()) return;
+ const windows = std.os.windows;
+ const S = struct {
+ var attrs: windows.WORD = undefined;
+ var init_attrs = false;
+ };
+ if (!S.init_attrs) {
+ S.init_attrs = true;
+ var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
+ _ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info);
+ S.attrs = info.wAttributes;
+ _ = windows.kernel32.SetConsoleOutputCP(65001);
+ }
+
+ // need to flush bufferedWriter
+ const T = if (@typeInfo(@TypeOf(w.context)) == .Pointer) @TypeOf(w.context.*) else @TypeOf(w.context);
+ if (T != void and @hasDecl(T, "flush")) w.context.flush() catch {};
+
+ switch (color) {
+ .reset => _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {},
+ .red => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {},
+ .green => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {},
+ .blue => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+ .cyan => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+ .purple => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+ .yellow => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {},
+ .white => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+ }
+ } else switch (color) {
+ .reset => w.writeAll("\x1b[0m") catch {},
+ .red => w.writeAll("\x1b[31;1m") catch {},
+ .green => w.writeAll("\x1b[32;1m") catch {},
+ .blue => w.writeAll("\x1b[34;1m") catch {},
+ .cyan => w.writeAll("\x1b[36;1m") catch {},
+ .purple => w.writeAll("\x1b[35;1m") catch {},
+ .yellow => w.writeAll("\x1b[93;1m") catch {},
+ .white => w.writeAll("\x1b[0m\x1b[1m") catch {},
+ }
+}
+
+pub fn errorDescription(err: anyerror) []const u8 {
+ return switch (err) {
+ error.OutOfMemory => "ran out of memory",
+ error.FileNotFound => "file not found",
+ error.IsDir => "is a directory",
+ error.NotDir => "is not a directory",
+ error.NotOpenForReading => "file is not open for reading",
+ error.NotOpenForWriting => "file is not open for writing",
+ error.InvalidUtf8 => "input is not valid UTF-8",
+ error.FileBusy => "file is busy",
+ error.NameTooLong => "file name is too long",
+ error.AccessDenied => "access denied",
+ error.FileTooBig => "file is too big",
+ error.ProcessFdQuotaExceeded, error.SystemFdQuotaExceeded => "ran out of file descriptors",
+ error.SystemResources => "ran out of system resources",
+ error.FatalError => "a fatal error occurred",
+ error.Unexpected => "an unexpected error occurred",
+ else => @errorName(err),
+ };
+}
deps/aro/Value.zig
@@ -0,0 +1,601 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const Compilation = @import("Compilation.zig");
+const Type = @import("Type.zig");
+
+const Value = @This();
+
+pub const ByteRange = struct {
+ start: u32,
+ end: u32,
+
+ pub fn len(self: ByteRange) u32 {
+ return self.end - self.start;
+ }
+
+ pub fn trim(self: ByteRange, amount: u32) ByteRange {
+ std.debug.assert(self.start <= self.end - amount);
+ return .{ .start = self.start, .end = self.end - amount };
+ }
+
+ pub fn slice(self: ByteRange, all_bytes: []const u8) []const u8 {
+ return all_bytes[self.start..self.end];
+ }
+};
+
+tag: Tag = .unavailable,
+data: union {
+ none: void,
+ int: u64,
+ float: f64,
+ bytes: ByteRange,
+} = .{ .none = {} },
+
+const Tag = enum {
+ unavailable,
+ nullptr_t,
+ /// int is used to store integer, boolean and pointer values
+ int,
+ float,
+ bytes,
+};
+
+pub fn zero(v: Value) Value {
+ return switch (v.tag) {
+ .int => int(0),
+ .float => float(0),
+ else => unreachable,
+ };
+}
+
+pub fn one(v: Value) Value {
+ return switch (v.tag) {
+ .int => int(1),
+ .float => float(1),
+ else => unreachable,
+ };
+}
+
+pub fn int(v: anytype) Value {
+ if (@TypeOf(v) == comptime_int or @typeInfo(@TypeOf(v)).Int.signedness == .unsigned)
+ return .{ .tag = .int, .data = .{ .int = v } }
+ else
+ return .{ .tag = .int, .data = .{ .int = @bitCast(@as(i64, v)) } };
+}
+
+pub fn float(v: anytype) Value {
+ return .{ .tag = .float, .data = .{ .float = v } };
+}
+
+pub fn bytes(start: u32, end: u32) Value {
+ return .{ .tag = .bytes, .data = .{ .bytes = .{ .start = start, .end = end } } };
+}
+
+pub fn signExtend(v: Value, old_ty: Type, comp: *Compilation) i64 {
+ const size = old_ty.sizeof(comp).?;
+ return switch (size) {
+ 1 => v.getInt(i8),
+ 2 => v.getInt(i16),
+ 4 => v.getInt(i32),
+ 8 => v.getInt(i64),
+ else => unreachable,
+ };
+}
+
+/// Number of bits needed to hold `v` which is of type `ty`.
+/// Asserts that `v` is not negative
+pub fn minUnsignedBits(v: Value, ty: Type, comp: *const Compilation) usize {
+ assert(v.compare(.gte, Value.int(0), ty, comp));
+ return switch (ty.sizeof(comp).?) {
+ 1 => 8 - @clz(v.getInt(u8)),
+ 2 => 16 - @clz(v.getInt(u16)),
+ 4 => 32 - @clz(v.getInt(u32)),
+ 8 => 64 - @clz(v.getInt(u64)),
+ else => unreachable,
+ };
+}
+
+test "minUnsignedBits" {
+ const Test = struct {
+ fn checkIntBits(comp: *const Compilation, specifier: Type.Specifier, v: u64, expected: usize) !void {
+ const val = Value.int(v);
+ try std.testing.expectEqual(expected, val.minUnsignedBits(.{ .specifier = specifier }, comp));
+ }
+ };
+
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+ comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
+
+ try Test.checkIntBits(&comp, .int, 0, 0);
+ try Test.checkIntBits(&comp, .int, 1, 1);
+ try Test.checkIntBits(&comp, .int, 2, 2);
+ try Test.checkIntBits(&comp, .int, std.math.maxInt(i8), 7);
+ try Test.checkIntBits(&comp, .int, std.math.maxInt(u8), 8);
+ try Test.checkIntBits(&comp, .int, std.math.maxInt(i16), 15);
+ try Test.checkIntBits(&comp, .int, std.math.maxInt(u16), 16);
+ try Test.checkIntBits(&comp, .int, std.math.maxInt(i32), 31);
+ try Test.checkIntBits(&comp, .uint, std.math.maxInt(u32), 32);
+ try Test.checkIntBits(&comp, .long, std.math.maxInt(i64), 63);
+ try Test.checkIntBits(&comp, .ulong, std.math.maxInt(u64), 64);
+ try Test.checkIntBits(&comp, .long_long, std.math.maxInt(i64), 63);
+ try Test.checkIntBits(&comp, .ulong_long, std.math.maxInt(u64), 64);
+}
+
+/// Minimum number of bits needed to represent `v` in 2's complement notation
+/// Asserts that `v` is negative.
+pub fn minSignedBits(v: Value, ty: Type, comp: *const Compilation) usize {
+ assert(v.compare(.lt, Value.int(0), ty, comp));
+ return switch (ty.sizeof(comp).?) {
+ 1 => 8 - @clz(~v.getInt(u8)) + 1,
+ 2 => 16 - @clz(~v.getInt(u16)) + 1,
+ 4 => 32 - @clz(~v.getInt(u32)) + 1,
+ 8 => 64 - @clz(~v.getInt(u64)) + 1,
+ else => unreachable,
+ };
+}
+
+test "minSignedBits" {
+ const Test = struct {
+ fn checkIntBits(comp: *const Compilation, specifier: Type.Specifier, v: i64, expected: usize) !void {
+ const val = Value.int(v);
+ try std.testing.expectEqual(expected, val.minSignedBits(.{ .specifier = specifier }, comp));
+ }
+ };
+
+ var comp = Compilation.init(std.testing.allocator);
+ defer comp.deinit();
+ comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
+
+ for ([_]Type.Specifier{ .int, .long, .long_long }) |specifier| {
+ try Test.checkIntBits(&comp, specifier, -1, 1);
+ try Test.checkIntBits(&comp, specifier, -2, 2);
+ try Test.checkIntBits(&comp, specifier, -10, 5);
+ try Test.checkIntBits(&comp, specifier, -101, 8);
+
+ try Test.checkIntBits(&comp, specifier, std.math.minInt(i8), 8);
+ try Test.checkIntBits(&comp, specifier, std.math.minInt(i16), 16);
+ try Test.checkIntBits(&comp, specifier, std.math.minInt(i32), 32);
+ }
+
+ try Test.checkIntBits(&comp, .long, std.math.minInt(i64), 64);
+ try Test.checkIntBits(&comp, .long_long, std.math.minInt(i64), 64);
+}
+
+pub const FloatToIntChangeKind = enum {
+ /// value did not change
+ none,
+ /// floating point number too small or large for destination integer type
+ out_of_range,
+ /// tried to convert a NaN or Infinity
+ overflow,
+ /// fractional value was converted to zero
+ nonzero_to_zero,
+ /// fractional part truncated
+ value_changed,
+};
+
+fn floatToIntExtra(comptime FloatTy: type, int_ty_signedness: std.builtin.Signedness, int_ty_size: u16, v: *Value) FloatToIntChangeKind {
+ const float_val = v.getFloat(FloatTy);
+ const was_zero = float_val == 0;
+ const had_fraction = std.math.modf(float_val).fpart != 0;
+
+ switch (int_ty_signedness) {
+ inline else => |signedness| switch (int_ty_size) {
+ inline 1, 2, 4, 8 => |bytecount| {
+ const IntTy = std.meta.Int(signedness, bytecount * 8);
+
+ const intVal = std.math.lossyCast(IntTy, float_val);
+ v.* = int(intVal);
+ if (!was_zero and v.isZero()) return .nonzero_to_zero;
+ if (float_val <= std.math.minInt(IntTy) or float_val >= std.math.maxInt(IntTy)) return .out_of_range;
+ if (had_fraction) return .value_changed;
+ return .none;
+ },
+ else => unreachable,
+ },
+ }
+}
+
+/// Converts the stored value from a float to an integer.
+/// `.unavailable` value remains unchanged.
+pub fn floatToInt(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) FloatToIntChangeKind {
+ assert(old_ty.isFloat());
+ if (v.tag == .unavailable) return .none;
+ if (new_ty.is(.bool)) {
+ const was_zero = v.isZero();
+ const was_one = v.getFloat(f64) == 1.0;
+ v.toBool();
+ if (was_zero or was_one) return .none;
+ return .value_changed;
+ } else if (new_ty.isUnsignedInt(comp) and v.data.float < 0) {
+ v.* = int(0);
+ return .out_of_range;
+ } else if (!std.math.isFinite(v.data.float)) {
+ v.tag = .unavailable;
+ return .overflow;
+ }
+ const old_size = old_ty.sizeof(comp).?;
+ const new_size: u16 = @intCast(new_ty.sizeof(comp).?);
+ if (new_ty.isUnsignedInt(comp)) switch (old_size) {
+ 1 => unreachable, // promoted to int
+ 2 => unreachable, // promoted to int
+ 4 => return floatToIntExtra(f32, .unsigned, new_size, v),
+ 8 => return floatToIntExtra(f64, .unsigned, new_size, v),
+ else => unreachable,
+ } else switch (old_size) {
+ 1 => unreachable, // promoted to int
+ 2 => unreachable, // promoted to int
+ 4 => return floatToIntExtra(f32, .signed, new_size, v),
+ 8 => return floatToIntExtra(f64, .signed, new_size, v),
+ else => unreachable,
+ }
+}
+
+/// Converts the stored value from an integer to a float.
+/// `.unavailable` value remains unchanged.
+pub fn intToFloat(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) void {
+ assert(old_ty.isInt());
+ if (v.tag == .unavailable) return;
+ if (!new_ty.isReal() or new_ty.sizeof(comp).? > 8) {
+ v.tag = .unavailable;
+ } else if (old_ty.isUnsignedInt(comp)) {
+ v.* = float(@as(f64, @floatFromInt(v.data.int)));
+ } else {
+ v.* = float(@as(f64, @floatFromInt(@as(i64, @bitCast(v.data.int)))));
+ }
+}
+
+/// Truncates or extends bits based on type.
+/// old_ty is only used for size.
+pub fn intCast(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) void {
+ // assert(old_ty.isInt() and new_ty.isInt());
+ if (v.tag == .unavailable) return;
+ if (new_ty.is(.bool)) return v.toBool();
+ if (!old_ty.isUnsignedInt(comp)) {
+ const size = new_ty.sizeof(comp).?;
+ switch (size) {
+ 1 => v.* = int(@as(u8, @truncate(@as(u64, @bitCast(v.signExtend(old_ty, comp)))))),
+ 2 => v.* = int(@as(u16, @truncate(@as(u64, @bitCast(v.signExtend(old_ty, comp)))))),
+ 4 => v.* = int(@as(u32, @truncate(@as(u64, @bitCast(v.signExtend(old_ty, comp)))))),
+ 8 => return,
+ else => unreachable,
+ }
+ }
+}
+
+/// Converts the stored value from an integer to a float.
+/// `.unavailable` value remains unchanged.
+pub fn floatCast(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) void {
+ assert(old_ty.isFloat() and new_ty.isFloat());
+ if (v.tag == .unavailable) return;
+ const size = new_ty.sizeof(comp).?;
+ if (!new_ty.isReal() or size > 8) {
+ v.tag = .unavailable;
+ } else if (size == 32) {
+ v.* = float(@as(f32, @floatCast(v.data.float)));
+ }
+}
+
+/// Truncates data.int to one bit
+pub fn toBool(v: *Value) void {
+ if (v.tag == .unavailable) return;
+ const res = v.getBool();
+ v.* = int(@intFromBool(res));
+}
+
+pub fn isZero(v: Value) bool {
+ return switch (v.tag) {
+ .unavailable => false,
+ .nullptr_t => false,
+ .int => v.data.int == 0,
+ .float => v.data.float == 0,
+ .bytes => false,
+ };
+}
+
+pub fn getBool(v: Value) bool {
+ return switch (v.tag) {
+ .unavailable => unreachable,
+ .nullptr_t => false,
+ .int => v.data.int != 0,
+ .float => v.data.float != 0,
+ .bytes => true,
+ };
+}
+
+pub fn getInt(v: Value, comptime T: type) T {
+ if (T == u64) return v.data.int;
+ return if (@typeInfo(T).Int.signedness == .unsigned)
+ @truncate(v.data.int)
+ else
+ @truncate(@as(i64, @bitCast(v.data.int)));
+}
+
+pub fn getFloat(v: Value, comptime T: type) T {
+ if (T == f64) return v.data.float;
+ return @floatCast(v.data.float);
+}
+
+const bin_overflow = struct {
+ inline fn addInt(comptime T: type, out: *Value, a: Value, b: Value) bool {
+ const a_val = a.getInt(T);
+ const b_val = b.getInt(T);
+ const sum, const overflowed = @addWithOverflow(a_val, b_val);
+ out.* = int(sum);
+ return overflowed != 0;
+ }
+ inline fn addFloat(comptime T: type, aa: Value, bb: Value) Value {
+ const a_val = aa.getFloat(T);
+ const b_val = bb.getFloat(T);
+ return float(a_val + b_val);
+ }
+
+ inline fn subInt(comptime T: type, out: *Value, a: Value, b: Value) bool {
+ const a_val = a.getInt(T);
+ const b_val = b.getInt(T);
+ const difference, const overflowed = @subWithOverflow(a_val, b_val);
+ out.* = int(difference);
+ return overflowed != 0;
+ }
+ inline fn subFloat(comptime T: type, aa: Value, bb: Value) Value {
+ const a_val = aa.getFloat(T);
+ const b_val = bb.getFloat(T);
+ return float(a_val - b_val);
+ }
+
+ inline fn mulInt(comptime T: type, out: *Value, a: Value, b: Value) bool {
+ const a_val = a.getInt(T);
+ const b_val = b.getInt(T);
+ const product, const overflowed = @mulWithOverflow(a_val, b_val);
+ out.* = int(product);
+ return overflowed != 0;
+ }
+ inline fn mulFloat(comptime T: type, aa: Value, bb: Value) Value {
+ const a_val = aa.getFloat(T);
+ const b_val = bb.getFloat(T);
+ return float(a_val * b_val);
+ }
+
+ const FT = fn (*Value, Value, Value, Type, *Compilation) bool;
+ fn getOp(comptime intFunc: anytype, comptime floatFunc: anytype) FT {
+ return struct {
+ fn op(res: *Value, a: Value, b: Value, ty: Type, comp: *Compilation) bool {
+ const size = ty.sizeof(comp).?;
+ if (@TypeOf(floatFunc) != @TypeOf(null) and ty.isFloat()) {
+ res.* = switch (size) {
+ 4 => floatFunc(f32, a, b),
+ 8 => floatFunc(f64, a, b),
+ else => unreachable,
+ };
+ return false;
+ }
+
+ if (ty.isUnsignedInt(comp)) switch (size) {
+ 1 => return intFunc(u8, res, a, b),
+ 2 => return intFunc(u16, res, a, b),
+ 4 => return intFunc(u32, res, a, b),
+ 8 => return intFunc(u64, res, a, b),
+ else => unreachable,
+ } else switch (size) {
+ 1 => return intFunc(u8, res, a, b),
+ 2 => return intFunc(u16, res, a, b),
+ 4 => return intFunc(i32, res, a, b),
+ 8 => return intFunc(i64, res, a, b),
+ else => unreachable,
+ }
+ }
+ }.op;
+ }
+};
+
+pub const add = bin_overflow.getOp(bin_overflow.addInt, bin_overflow.addFloat);
+pub const sub = bin_overflow.getOp(bin_overflow.subInt, bin_overflow.subFloat);
+pub const mul = bin_overflow.getOp(bin_overflow.mulInt, bin_overflow.mulFloat);
+
+const bin_ops = struct {
+ inline fn divInt(comptime T: type, aa: Value, bb: Value) Value {
+ const a_val = aa.getInt(T);
+ const b_val = bb.getInt(T);
+ return int(@divTrunc(a_val, b_val));
+ }
+ inline fn divFloat(comptime T: type, aa: Value, bb: Value) Value {
+ const a_val = aa.getFloat(T);
+ const b_val = bb.getFloat(T);
+ return float(a_val / b_val);
+ }
+
+ inline fn remInt(comptime T: type, a: Value, b: Value) Value {
+ const a_val = a.getInt(T);
+ const b_val = b.getInt(T);
+
+ if (@typeInfo(T).Int.signedness == .signed) {
+ if (a_val == std.math.minInt(T) and b_val == -1) {
+ return Value{ .tag = .unavailable, .data = .{ .none = {} } };
+ } else {
+ if (b_val > 0) return int(@rem(a_val, b_val));
+ return int(a_val - @divTrunc(a_val, b_val) * b_val);
+ }
+ } else {
+ return int(a_val % b_val);
+ }
+ }
+
+ inline fn orInt(comptime T: type, a: Value, b: Value) Value {
+ const a_val = a.getInt(T);
+ const b_val = b.getInt(T);
+ return int(a_val | b_val);
+ }
+ inline fn xorInt(comptime T: type, a: Value, b: Value) Value {
+ const a_val = a.getInt(T);
+ const b_val = b.getInt(T);
+ return int(a_val ^ b_val);
+ }
+ inline fn andInt(comptime T: type, a: Value, b: Value) Value {
+ const a_val = a.getInt(T);
+ const b_val = b.getInt(T);
+ return int(a_val & b_val);
+ }
+
+ inline fn shl(comptime T: type, a: Value, b: Value) Value {
+ const ShiftT = std.math.Log2Int(T);
+ const info = @typeInfo(T).Int;
+ const UT = std.meta.Int(.unsigned, info.bits);
+ const b_val = b.getInt(T);
+
+ if (b_val > std.math.maxInt(ShiftT)) {
+ return if (info.signedness == .unsigned)
+ int(@as(UT, std.math.maxInt(UT)))
+ else
+ int(@as(T, std.math.minInt(T)));
+ }
+ const amt: ShiftT = @truncate(@as(UT, @bitCast(b_val)));
+ const a_val = a.getInt(T);
+ return int(a_val << amt);
+ }
+ inline fn shr(comptime T: type, a: Value, b: Value) Value {
+ const ShiftT = std.math.Log2Int(T);
+ const UT = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
+
+ const b_val = b.getInt(T);
+ if (b_val > std.math.maxInt(ShiftT)) return Value.int(0);
+
+ const amt: ShiftT = @truncate(@as(UT, @intCast(b_val)));
+ const a_val = a.getInt(T);
+ return int(a_val >> amt);
+ }
+
+ const FT = fn (Value, Value, Type, *Compilation) Value;
+ fn getOp(comptime intFunc: anytype, comptime floatFunc: anytype) FT {
+ return struct {
+ fn op(a: Value, b: Value, ty: Type, comp: *Compilation) Value {
+ const size = ty.sizeof(comp).?;
+ if (@TypeOf(floatFunc) != @TypeOf(null) and ty.isFloat()) {
+ switch (size) {
+ 4 => return floatFunc(f32, a, b),
+ 8 => return floatFunc(f64, a, b),
+ else => unreachable,
+ }
+ }
+
+ if (ty.isUnsignedInt(comp)) switch (size) {
+ 1 => unreachable, // promoted to int
+ 2 => unreachable, // promoted to int
+ 4 => return intFunc(u32, a, b),
+ 8 => return intFunc(u64, a, b),
+ else => unreachable,
+ } else switch (size) {
+ 1 => unreachable, // promoted to int
+ 2 => unreachable, // promoted to int
+ 4 => return intFunc(i32, a, b),
+ 8 => return intFunc(i64, a, b),
+ else => unreachable,
+ }
+ }
+ }.op;
+ }
+};
+
+/// caller guarantees rhs != 0
+pub const div = bin_ops.getOp(bin_ops.divInt, bin_ops.divFloat);
+/// caller guarantees rhs != 0
+/// caller guarantees lhs != std.math.minInt(T) OR rhs != -1
+pub const rem = bin_ops.getOp(bin_ops.remInt, null);
+
+pub const bitOr = bin_ops.getOp(bin_ops.orInt, null);
+pub const bitXor = bin_ops.getOp(bin_ops.xorInt, null);
+pub const bitAnd = bin_ops.getOp(bin_ops.andInt, null);
+
+pub const shl = bin_ops.getOp(bin_ops.shl, null);
+pub const shr = bin_ops.getOp(bin_ops.shr, null);
+
+pub fn bitNot(v: Value, ty: Type, comp: *Compilation) Value {
+ const size = ty.sizeof(comp).?;
+ var out: Value = undefined;
+ if (ty.isUnsignedInt(comp)) switch (size) {
+ 1 => unreachable, // promoted to int
+ 2 => unreachable, // promoted to int
+ 4 => out = int(~v.getInt(u32)),
+ 8 => out = int(~v.getInt(u64)),
+ else => unreachable,
+ } else switch (size) {
+ 1 => unreachable, // promoted to int
+ 2 => unreachable, // promoted to int
+ 4 => out = int(~v.getInt(i32)),
+ 8 => out = int(~v.getInt(i64)),
+ else => unreachable,
+ }
+ return out;
+}
+
+pub fn compare(a: Value, op: std.math.CompareOperator, b: Value, ty: Type, comp: *const Compilation) bool {
+ assert(a.tag == b.tag);
+ if (a.tag == .nullptr_t) {
+ return switch (op) {
+ .eq => true,
+ .neq => false,
+ else => unreachable,
+ };
+ }
+ const S = struct {
+ inline fn doICompare(comptime T: type, aa: Value, opp: std.math.CompareOperator, bb: Value) bool {
+ const a_val = aa.getInt(T);
+ const b_val = bb.getInt(T);
+ return std.math.compare(a_val, opp, b_val);
+ }
+ inline fn doFCompare(comptime T: type, aa: Value, opp: std.math.CompareOperator, bb: Value) bool {
+ const a_val = aa.getFloat(T);
+ const b_val = bb.getFloat(T);
+ return std.math.compare(a_val, opp, b_val);
+ }
+ };
+ const size = ty.sizeof(comp).?;
+ switch (a.tag) {
+ .unavailable => return true,
+ .int => if (ty.isUnsignedInt(comp)) switch (size) {
+ 1 => return S.doICompare(u8, a, op, b),
+ 2 => return S.doICompare(u16, a, op, b),
+ 4 => return S.doICompare(u32, a, op, b),
+ 8 => return S.doICompare(u64, a, op, b),
+ else => unreachable,
+ } else switch (size) {
+ 1 => return S.doICompare(i8, a, op, b),
+ 2 => return S.doICompare(i16, a, op, b),
+ 4 => return S.doICompare(i32, a, op, b),
+ 8 => return S.doICompare(i64, a, op, b),
+ else => unreachable,
+ },
+ .float => switch (size) {
+ 4 => return S.doFCompare(f32, a, op, b),
+ 8 => return S.doFCompare(f64, a, op, b),
+ else => unreachable,
+ },
+ else => @panic("TODO"),
+ }
+ return false;
+}
+
+pub fn hash(v: Value) u64 {
+ switch (v.tag) {
+ .unavailable => unreachable,
+ .int => return std.hash.Wyhash.hash(0, std.mem.asBytes(&v.data.int)),
+ else => @panic("TODO"),
+ }
+}
+
+pub fn dump(v: Value, ty: Type, comp: *Compilation, strings: []const u8, w: anytype) !void {
+ switch (v.tag) {
+ .unavailable => try w.writeAll("unavailable"),
+ .int => if (ty.is(.bool) and comp.langopts.standard.atLeast(.c2x)) {
+ try w.print("{s}", .{if (v.isZero()) "false" else "true"});
+ } else if (ty.isUnsignedInt(comp)) {
+ try w.print("{d}", .{v.data.int});
+ } else {
+ try w.print("{d}", .{v.signExtend(ty, comp)});
+ },
+ .bytes => try w.print("\"{s}\"", .{v.data.bytes.slice(strings)}),
+ // std.fmt does @as instead of @floatCast
+ .float => try w.print("{d}", .{@as(f64, @floatCast(v.data.float))}),
+ else => try w.print("({s})", .{@tagName(v.tag)}),
+ }
+}
.gitattributes
@@ -10,3 +10,4 @@ lib/libcxx/** linguist-vendored
lib/libcxxabi/** linguist-vendored
lib/libunwind/** linguist-vendored
lib/tsan/** linguist-vendored
+deps/** linguist-vendored
build.zig
@@ -580,6 +580,9 @@ fn addCompilerStep(
.optimize = optimize,
});
exe.stack_size = stack_size;
+ exe.addAnonymousModule("aro", .{
+ .source_file = .{ .path = "deps/aro/lib.zig" },
+ });
return exe;
}
CMakeLists.txt
@@ -797,7 +797,8 @@ set(BUILD_ZIG2_ARGS
-OReleaseSmall
--name zig2 -femit-bin="${ZIG2_C_SOURCE}"
--mod "build_options::${ZIG_CONFIG_ZIG_OUT}"
- --deps build_options
+ --mod "aro::deps/aro/lib.zig"
+ --deps build_options,aro
-target "${ZIG_HOST_TARGET_TRIPLE}"
)