Commit e98630aacf

Alex Rønne Petersen <alex@alexrp.com>
2025-09-26 02:03:58
aro: TypeStore: synchronize __va_list_tag logic with Zig's std.builtin.VaList
https://github.com/Vexu/arocc/pull/893 closes #25361
1 parent d16ff4d
Changed files (1)
lib
compiler
lib/compiler/aro/aro/TypeStore.zig
@@ -2046,27 +2046,69 @@ fn generateNsConstantStringType(ts: *TypeStore, comp: *Compilation) !QualType {
 }
 
 fn generateVaListType(ts: *TypeStore, comp: *Compilation) !QualType {
-    const Kind = enum { aarch64_va_list, x86_64_va_list };
+    const Kind = enum {
+        aarch64_va_list,
+        arm_va_list,
+        hexagon_va_list,
+        powerpc_va_list,
+        s390x_va_list,
+        x86_64_va_list,
+        xtensa_va_list,
+    };
     const kind: Kind = switch (comp.target.cpu.arch) {
+        .amdgcn,
+        .msp430,
+        .nvptx,
+        .nvptx64,
+        .powerpc64,
+        .powerpc64le,
+        .x86,
+        => return .char_pointer,
+        .arc,
+        .avr,
+        .bpfel,
+        .bpfeb,
+        .csky,
+        .lanai,
+        .loongarch32,
+        .loongarch64,
+        .m68k,
+        .mips,
+        .mipsel,
+        .mips64,
+        .mips64el,
+        .riscv32,
+        .riscv32be,
+        .riscv64,
+        .riscv64be,
+        .sparc,
+        .sparc64,
+        .spirv32,
+        .spirv64,
+        .ve,
+        .wasm32,
+        .wasm64,
+        .xcore,
+        => return .void_pointer,
         .aarch64, .aarch64_be => switch (comp.target.os.tag) {
-            .windows => return .char_pointer,
-            .ios, .macos, .tvos, .watchos => return .char_pointer,
+            .driverkit, .ios, .macos, .tvos, .visionos, .watchos, .windows => return .char_pointer,
             else => .aarch64_va_list,
         },
-        .arm, .armeb, .thumb, .thumbeb => switch (comp.target.os.tag) {
-            .ios, .macos, .tvos, .watchos, .visionos => return .char_pointer,
-            else => return .void_pointer,
-        },
-        .sparc, .wasm32, .wasm64, .bpfel, .bpfeb, .riscv32, .riscv64, .avr, .spirv32, .spirv64 => return .void_pointer,
-        .powerpc => switch (comp.target.os.tag) {
-            .ios, .macos, .tvos, .watchos, .aix => return .char_pointer,
-            else => return .void, // unknown
+        .arm, .armeb, .thumb, .thumbeb => .arm_va_list,
+        .hexagon => if (comp.target.abi.isMusl())
+            .hexagon_va_list
+        else
+            return .char_pointer,
+        .powerpc, .powerpcle => switch (comp.target.os.tag) {
+            .aix => return .char_pointer,
+            else => .powerpc_va_list,
         },
-        .x86, .msp430 => return .char_pointer,
+        .s390x => .s390x_va_list,
         .x86_64 => switch (comp.target.os.tag) {
-            .windows => return .char_pointer,
+            .uefi, .windows => return .char_pointer,
             else => .x86_64_va_list,
         },
+        .xtensa => .xtensa_va_list,
         else => return .void, // unknown
     };
 
@@ -2093,6 +2135,87 @@ fn generateVaListType(ts: *TypeStore, comp: *Compilation) !QualType {
 
             break :blk qt;
         },
+        .arm_va_list => blk: {
+            var record: Type.Record = .{
+                .name = try comp.internString("__va_list_tag"),
+                .decl_node = undefined, // TODO
+                .layout = null,
+                .fields = &.{},
+            };
+            const qt = try ts.put(comp.gpa, .{ .@"struct" = record });
+
+            var fields: [1]Type.Record.Field = .{
+                .{ .name = try comp.internString("__ap"), .qt = .void_pointer },
+            };
+            record.fields = &fields;
+            record.layout = record_layout.compute(&fields, qt, comp, null) catch unreachable;
+            try ts.set(comp.gpa, .{ .@"struct" = record }, @intFromEnum(qt._index));
+
+            break :blk qt;
+        },
+        .hexagon_va_list => blk: {
+            var record: Type.Record = .{
+                .name = try comp.internString("__va_list_tag"),
+                .decl_node = undefined, // TODO
+                .layout = null,
+                .fields = &.{},
+            };
+            const qt = try ts.put(comp.gpa, .{ .@"struct" = record });
+
+            var fields: [4]Type.Record.Field = .{
+                .{ .name = try comp.internString("__gpr"), .qt = .long },
+                .{ .name = try comp.internString("__fpr"), .qt = .long },
+                .{ .name = try comp.internString("__overflow_arg_area"), .qt = .void_pointer },
+                .{ .name = try comp.internString("__reg_save_area"), .qt = .void_pointer },
+            };
+            record.fields = &fields;
+            record.layout = record_layout.compute(&fields, qt, comp, null) catch unreachable;
+            try ts.set(comp.gpa, .{ .@"struct" = record }, @intFromEnum(qt._index));
+
+            break :blk qt;
+        },
+        .powerpc_va_list => blk: {
+            var record: Type.Record = .{
+                .name = try comp.internString("__va_list_tag"),
+                .decl_node = undefined, // TODO
+                .layout = null,
+                .fields = &.{},
+            };
+            const qt = try ts.put(comp.gpa, .{ .@"struct" = record });
+
+            var fields: [5]Type.Record.Field = .{
+                .{ .name = try comp.internString("gpr"), .qt = .uchar },
+                .{ .name = try comp.internString("fpr"), .qt = .uchar },
+                .{ .name = try comp.internString("reserved"), .qt = .ushort },
+                .{ .name = try comp.internString("overflow_arg_area"), .qt = .void_pointer },
+                .{ .name = try comp.internString("reg_save_area"), .qt = .void_pointer },
+            };
+            record.fields = &fields;
+            record.layout = record_layout.compute(&fields, qt, comp, null) catch unreachable;
+            try ts.set(comp.gpa, .{ .@"struct" = record }, @intFromEnum(qt._index));
+
+            break :blk qt;
+        },
+        .s390x_va_list => blk: {
+            var record: Type.Record = .{
+                .name = try comp.internString("__va_list_tag"),
+                .decl_node = undefined, // TODO
+                .layout = null,
+                .fields = &.{},
+            };
+            const qt = try ts.put(comp.gpa, .{ .@"struct" = record });
+
+            var fields: [3]Type.Record.Field = .{
+                .{ .name = try comp.internString("__current_saved_reg_area_pointer"), .qt = .void_pointer },
+                .{ .name = try comp.internString("__saved_reg_area_end_pointer"), .qt = .void_pointer },
+                .{ .name = try comp.internString("__overflow_area_pointer"), .qt = .void_pointer },
+            };
+            record.fields = &fields;
+            record.layout = record_layout.compute(&fields, qt, comp, null) catch unreachable;
+            try ts.set(comp.gpa, .{ .@"struct" = record }, @intFromEnum(qt._index));
+
+            break :blk qt;
+        },
         .x86_64_va_list => blk: {
             var record: Type.Record = .{
                 .name = try comp.internString("__va_list_tag"),
@@ -2112,6 +2235,26 @@ fn generateVaListType(ts: *TypeStore, comp: *Compilation) !QualType {
             record.layout = record_layout.compute(&fields, qt, comp, null) catch unreachable;
             try ts.set(comp.gpa, .{ .@"struct" = record }, @intFromEnum(qt._index));
 
+            break :blk qt;
+        },
+        .xtensa_va_list => blk: {
+            var record: Type.Record = .{
+                .name = try comp.internString("__va_list_tag"),
+                .decl_node = undefined, // TODO
+                .layout = null,
+                .fields = &.{},
+            };
+            const qt = try ts.put(comp.gpa, .{ .@"struct" = record });
+
+            var fields: [3]Type.Record.Field = .{
+                .{ .name = try comp.internString("__va_stk"), .qt = .int_pointer },
+                .{ .name = try comp.internString("__va_reg"), .qt = .int_pointer },
+                .{ .name = try comp.internString("__va_ndx"), .qt = .int },
+            };
+            record.fields = &fields;
+            record.layout = record_layout.compute(&fields, qt, comp, null) catch unreachable;
+            try ts.set(comp.gpa, .{ .@"struct" = record }, @intFromEnum(qt._index));
+
             break :blk qt;
         },
     };