master
   1b: *std.Build,
   2options: Options,
   3root_step: *std.Build.Step,
   4
   5pub const Options = struct {
   6    test_filters: []const []const u8,
   7    test_target_filters: []const []const u8,
   8    gdb: ?[]const u8,
   9    lldb: ?[]const u8,
  10    optimize_modes: []const std.builtin.OptimizeMode,
  11    skip_single_threaded: bool,
  12    skip_libc: bool,
  13};
  14
  15pub const Target = struct {
  16    resolved: std.Build.ResolvedTarget,
  17    optimize_mode: std.builtin.OptimizeMode = .Debug,
  18    link_libc: ?bool = null,
  19    single_threaded: ?bool = null,
  20    pic: ?bool = null,
  21    test_name_suffix: []const u8,
  22};
  23
  24pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
  25    db.addLldbTest(
  26        "basic",
  27        target,
  28        &.{
  29            .{
  30                .path = "basic.zig",
  31                .source =
  32                \\const Basic = struct {
  33                \\    void: void = {},
  34                \\    bool_false: bool = false,
  35                \\    bool_true: bool = true,
  36                \\    u0_0: u0 = 0,
  37                \\    u1_0: u1 = 0,
  38                \\    u1_1: u1 = 1,
  39                \\    u2_0: u2 = 0,
  40                \\    u2_3: u2 = 3,
  41                \\    u3_0: u3 = 0,
  42                \\    u3_7: u3 = 7,
  43                \\    u4_0: u4 = 0,
  44                \\    u4_15: u4 = 15,
  45                \\    u5_0: u5 = 0,
  46                \\    u5_31: u5 = 31,
  47                \\    u6_0: u6 = 0,
  48                \\    u6_63: u6 = 63,
  49                \\    u7_0: u7 = 0,
  50                \\    u7_127: u7 = 127,
  51                \\    u8_0: u8 = 0,
  52                \\    u8_255: u8 = 255,
  53                \\    u16_0: u16 = 0,
  54                \\    u16_65535: u16 = 65535,
  55                \\    u24_0: u24 = 0,
  56                \\    u24_16777215: u24 = 16777215,
  57                \\    u32_0: u32 = 0,
  58                \\    u32_4294967295: u32 = 4294967295,
  59                \\    i0_0: i0 = 0,
  60                \\    @"i1_-1": i1 = -1,
  61                \\    i1_0: i1 = 0,
  62                \\    @"i2_-2": i2 = -2,
  63                \\    i2_0: i2 = 0,
  64                \\    i2_1: i2 = 1,
  65                \\    @"i3_-4": i3 = -4,
  66                \\    i3_0: i3 = 0,
  67                \\    i3_3: i3 = 3,
  68                \\    @"i4_-8": i4 = -8,
  69                \\    i4_0: i4 = 0,
  70                \\    i4_7: i4 = 7,
  71                \\    @"i5_-16": i5 = -16,
  72                \\    i5_0: i5 = 0,
  73                \\    i5_15: i5 = 15,
  74                \\    @"i6_-32": i6 = -32,
  75                \\    i6_0: i6 = 0,
  76                \\    i6_31: i6 = 31,
  77                \\    @"i7_-64": i7 = -64,
  78                \\    i7_0: i7 = 0,
  79                \\    i7_63: i7 = 63,
  80                \\    @"i8_-128": i8 = -128,
  81                \\    i8_0: i8 = 0,
  82                \\    i8_127: i8 = 127,
  83                \\    @"i16_-32768": i16 = -32768,
  84                \\    i16_0: i16 = 0,
  85                \\    i16_32767: i16 = 32767,
  86                \\    @"i24_-8388608": i24 = -8388608,
  87                \\    i24_0: i24 = 0,
  88                \\    i24_8388607: i24 = 8388607,
  89                \\    @"i32_-2147483648": i32 = -2147483648,
  90                \\    i32_0: i32 = 0,
  91                \\    i32_2147483647: i32 = 2147483647,
  92                \\    @"f16_42.625": f16 = 42.625,
  93                \\    @"f32_-2730.65625": f32 = -2730.65625,
  94                \\    @"f64_357913941.33203125": f64 = 357913941.33203125,
  95                \\    @"f80_-91625968981.3330078125": f80 = -91625968981.3330078125,
  96                \\    @"f128_384307168202282325.333332061767578125": f128 = 384307168202282325.333332061767578125,
  97                \\};
  98                \\fn testBasic(basic: Basic) void {
  99                \\    _ = basic;
 100                \\}
 101                \\pub fn main() void {
 102                \\    testBasic(.{});
 103                \\}
 104                \\
 105                ,
 106            },
 107        },
 108        \\breakpoint set --file basic.zig --source-pattern-regexp '_ = basic;'
 109        \\process launch
 110        \\frame variable --show-types -- basic
 111        \\breakpoint delete --force 1
 112    ,
 113        &.{
 114            \\(lldb) frame variable --show-types -- basic
 115            \\(root.basic.Basic) basic = {
 116            \\  (void) .void = {}
 117            \\  (bool) .bool_false = false
 118            \\  (bool) .bool_true = true
 119            \\  (u0) .u0_0 = 0
 120            \\  (u1) .u1_0 = 0
 121            \\  (u1) .u1_1 = 1
 122            \\  (u2) .u2_0 = 0
 123            \\  (u2) .u2_3 = 3
 124            \\  (u3) .u3_0 = 0
 125            \\  (u3) .u3_7 = 7
 126            \\  (u4) .u4_0 = 0
 127            \\  (u4) .u4_15 = 15
 128            \\  (u5) .u5_0 = 0
 129            \\  (u5) .u5_31 = 31
 130            \\  (u6) .u6_0 = 0
 131            \\  (u6) .u6_63 = 63
 132            \\  (u7) .u7_0 = 0
 133            \\  (u7) .u7_127 = 127
 134            \\  (u8) .u8_0 = 0
 135            \\  (u8) .u8_255 = 255
 136            \\  (u16) .u16_0 = 0
 137            \\  (u16) .u16_65535 = 65535
 138            \\  (u24) .u24_0 = 0
 139            \\  (u24) .u24_16777215 = 16777215
 140            \\  (u32) .u32_0 = 0
 141            \\  (u32) .u32_4294967295 = 4294967295
 142            \\  (i0) .i0_0 = 0
 143            \\  (i1) .@"i1_-1" = -1
 144            \\  (i1) .i1_0 = 0
 145            \\  (i2) .@"i2_-2" = -2
 146            \\  (i2) .i2_0 = 0
 147            \\  (i2) .i2_1 = 1
 148            \\  (i3) .@"i3_-4" = -4
 149            \\  (i3) .i3_0 = 0
 150            \\  (i3) .i3_3 = 3
 151            \\  (i4) .@"i4_-8" = -8
 152            \\  (i4) .i4_0 = 0
 153            \\  (i4) .i4_7 = 7
 154            \\  (i5) .@"i5_-16" = -16
 155            \\  (i5) .i5_0 = 0
 156            \\  (i5) .i5_15 = 15
 157            \\  (i6) .@"i6_-32" = -32
 158            \\  (i6) .i6_0 = 0
 159            \\  (i6) .i6_31 = 31
 160            \\  (i7) .@"i7_-64" = -64
 161            \\  (i7) .i7_0 = 0
 162            \\  (i7) .i7_63 = 63
 163            \\  (i8) .@"i8_-128" = -128
 164            \\  (i8) .i8_0 = 0
 165            \\  (i8) .i8_127 = 127
 166            \\  (i16) .@"i16_-32768" = -32768
 167            \\  (i16) .i16_0 = 0
 168            \\  (i16) .i16_32767 = 32767
 169            \\  (i24) .@"i24_-8388608" = -8388608
 170            \\  (i24) .i24_0 = 0
 171            \\  (i24) .i24_8388607 = 8388607
 172            \\  (i32) .@"i32_-2147483648" = -2147483648
 173            \\  (i32) .i32_0 = 0
 174            \\  (i32) .i32_2147483647 = 2147483647
 175            \\  (f16) .@"f16_42.625" = 42.625
 176            \\  (f32) .@"f32_-2730.65625" = -2730.65625
 177            \\  (f64) .@"f64_357913941.33203125" = 357913941.33203125
 178            \\  (f80) .@"f80_-91625968981.3330078125" = -91625968981.3330078125
 179            \\  (f128) .@"f128_384307168202282325.333332061767578125" = 384307168202282325.333332061767578125
 180            \\}
 181            \\(lldb) breakpoint delete --force 1
 182            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 183        },
 184    );
 185    db.addLldbTest(
 186        "pointers",
 187        target,
 188        &.{
 189            .{
 190                .path = "pointers.zig",
 191                .source =
 192                \\const Pointers = struct {
 193                \\    var array: [7]u32 = .{
 194                \\        3010,
 195                \\        3014,
 196                \\        3018,
 197                \\        3022,
 198                \\        3026,
 199                \\        3030,
 200                \\        3034,
 201                \\    };
 202                \\
 203                \\    single: *u32 = @ptrFromInt(0x1010),
 204                \\    single_const: *const u32 = @ptrFromInt(0x1014),
 205                \\    single_volatile: *volatile u32 = @ptrFromInt(0x1018),
 206                \\    single_const_volatile: *const volatile u32 = @ptrFromInt(0x101c),
 207                \\    single_allowzero: *allowzero u32 = @ptrFromInt(0x1020),
 208                \\    single_allowzero_const: *allowzero const u32 = @ptrFromInt(0x1024),
 209                \\    single_allowzero_volatile: *allowzero volatile u32 = @ptrFromInt(0x1028),
 210                \\    single_allowzero_const_volatile: *allowzero const volatile u32 = @ptrFromInt(0x102c),
 211                \\
 212                \\    many: [*]u32 = @ptrFromInt(0x2010),
 213                \\    many_const: [*]const u32 = @ptrFromInt(0x2014),
 214                \\    many_volatile: [*]volatile u32 = @ptrFromInt(0x2018),
 215                \\    many_const_volatile: [*]const volatile u32 = @ptrFromInt(0x201c),
 216                \\    many_allowzero: [*]allowzero u32 = @ptrFromInt(0x2020),
 217                \\    many_allowzero_const: [*]allowzero const u32 = @ptrFromInt(0x2024),
 218                \\    many_allowzero_volatile: [*]allowzero volatile u32 = @ptrFromInt(0x2028),
 219                \\    many_allowzero_const_volatile: [*]allowzero const volatile u32 = @ptrFromInt(0x202c),
 220                \\    slice: []u32 = array[0..1],
 221                \\    slice_const: []const u32 = array[0..2],
 222                \\    slice_volatile: []volatile u32 = array[0..3],
 223                \\    slice_const_volatile: []const volatile u32 = array[0..4],
 224                \\    slice_allowzero: []allowzero u32 = array[4..4],
 225                \\    slice_allowzero_const: []allowzero const u32 = array[4..5],
 226                \\    slice_allowzero_volatile: []allowzero volatile u32 = array[4..6],
 227                \\    slice_allowzero_const_volatile: []allowzero const volatile u32 = array[4..7],
 228                \\
 229                \\    c: [*c]u32 = @ptrFromInt(0x4010),
 230                \\    c_const: [*c]const u32 = @ptrFromInt(0x4014),
 231                \\    c_volatile: [*c]volatile u32 = @ptrFromInt(0x4018),
 232                \\    c_const_volatile: [*c]const volatile u32 = @ptrFromInt(0x401c),
 233                \\};
 234                \\fn testPointers(pointers: Pointers) void {
 235                \\    _ = pointers;
 236                \\}
 237                \\pub fn main() void {
 238                \\    testPointers(.{});
 239                \\}
 240                \\
 241                ,
 242            },
 243        },
 244        \\breakpoint set --file pointers.zig --source-pattern-regexp '_ = pointers;'
 245        \\process launch
 246        \\frame variable --show-types -- pointers
 247        \\breakpoint delete --force 1
 248    ,
 249        &.{
 250            \\(lldb) frame variable --show-types -- pointers
 251            \\(root.pointers.Pointers) pointers = {
 252            \\  (*u32) .single = 0x0000000000001010
 253            \\  (*const u32) .single_const = 0x0000000000001014
 254            \\  (*volatile u32) .single_volatile = 0x0000000000001018
 255            \\  (*const volatile u32) .single_const_volatile = 0x000000000000101c
 256            \\  (*allowzero u32) .single_allowzero = 0x0000000000001020
 257            \\  (*allowzero const u32) .single_allowzero_const = 0x0000000000001024
 258            \\  (*allowzero volatile u32) .single_allowzero_volatile = 0x0000000000001028
 259            \\  (*allowzero const volatile u32) .single_allowzero_const_volatile = 0x000000000000102c
 260            \\  ([*]u32) .many = 0x0000000000002010
 261            \\  ([*]const u32) .many_const = 0x0000000000002014
 262            \\  ([*]volatile u32) .many_volatile = 0x0000000000002018
 263            \\  ([*]const volatile u32) .many_const_volatile = 0x000000000000201c
 264            \\  ([*]allowzero u32) .many_allowzero = 0x0000000000002020
 265            \\  ([*]allowzero const u32) .many_allowzero_const = 0x0000000000002024
 266            \\  ([*]allowzero volatile u32) .many_allowzero_volatile = 0x0000000000002028
 267            \\  ([*]allowzero const volatile u32) .many_allowzero_const_volatile = 0x000000000000202c
 268            \\  ([]u32) .slice = len=1 {
 269            \\    (u32) [0] = 3010
 270            \\  }
 271            \\  ([]const u32) .slice_const = len=2 {
 272            \\    (u32) [0] = 3010
 273            \\    (u32) [1] = 3014
 274            \\  }
 275            \\  ([]volatile u32) .slice_volatile = len=3 {
 276            \\    (u32) [0] = 3010
 277            \\    (u32) [1] = 3014
 278            \\    (u32) [2] = 3018
 279            \\  }
 280            \\  ([]const volatile u32) .slice_const_volatile = len=4 {
 281            \\    (u32) [0] = 3010
 282            \\    (u32) [1] = 3014
 283            \\    (u32) [2] = 3018
 284            \\    (u32) [3] = 3022
 285            \\  }
 286            \\  ([]allowzero u32) .slice_allowzero = len=0 {}
 287            \\  ([]allowzero const u32) .slice_allowzero_const = len=1 {
 288            \\    (u32) [0] = 3026
 289            \\  }
 290            \\  ([]allowzero volatile u32) .slice_allowzero_volatile = len=2 {
 291            \\    (u32) [0] = 3026
 292            \\    (u32) [1] = 3030
 293            \\  }
 294            \\  ([]allowzero const volatile u32) .slice_allowzero_const_volatile = len=3 {
 295            \\    (u32) [0] = 3026
 296            \\    (u32) [1] = 3030
 297            \\    (u32) [2] = 3034
 298            \\  }
 299            \\  ([*c]u32) .c = 0x0000000000004010
 300            \\  ([*c]const u32) .c_const = 0x0000000000004014
 301            \\  ([*c]volatile u32) .c_volatile = 0x0000000000004018
 302            \\  ([*c]const volatile u32) .c_const_volatile = 0x000000000000401c
 303            \\}
 304            \\(lldb) breakpoint delete --force 1
 305            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 306        },
 307    );
 308    db.addLldbTest(
 309        "strings",
 310        target,
 311        &.{
 312            .{
 313                .path = "strings.zig",
 314                .source =
 315                \\const Strings = struct {
 316                \\    c_ptr: [*c]const u8 = "c_ptr\x07\x08\t",
 317                \\    many_ptr: [*:0]const u8 = "many_ptr\n\x0b\x0c",
 318                \\    ptr_array: *const [12:0]u8 = "ptr_array\x00\r\x1b",
 319                \\    slice: [:0]const u8 = "slice\"\'\\\x00",
 320                \\};
 321                \\fn testStrings(strings: Strings) void {
 322                \\    _ = strings;
 323                \\}
 324                \\pub fn main() void {
 325                \\    testStrings(.{});
 326                \\}
 327                \\
 328                ,
 329            },
 330        },
 331        \\breakpoint set --file strings.zig --source-pattern-regexp '_ = strings;'
 332        \\process launch
 333        \\frame variable --show-types -- strings.slice
 334        \\frame variable --show-types --format character -- strings.slice
 335        \\frame variable --show-types --format c-string -- strings
 336        \\breakpoint delete --force 1
 337    ,
 338        &.{
 339            \\(lldb) frame variable --show-types -- strings.slice
 340            \\([:0]const u8) strings.slice = len=9 {
 341            \\  (u8) [0] = 115
 342            \\  (u8) [1] = 108
 343            \\  (u8) [2] = 105
 344            \\  (u8) [3] = 99
 345            \\  (u8) [4] = 101
 346            \\  (u8) [5] = 34
 347            \\  (u8) [6] = 39
 348            \\  (u8) [7] = 92
 349            \\  (u8) [8] = 0
 350            \\}
 351            \\(lldb) frame variable --show-types --format character -- strings.slice
 352            \\([:0]const u8) strings.slice = len=9 {
 353            \\  (u8) [0] = 's'
 354            \\  (u8) [1] = 'l'
 355            \\  (u8) [2] = 'i'
 356            \\  (u8) [3] = 'c'
 357            \\  (u8) [4] = 'e'
 358            \\  (u8) [5] = '\"'
 359            \\  (u8) [6] = '\''
 360            \\  (u8) [7] = '\\'
 361            \\  (u8) [8] = '\x00'
 362            \\}
 363            \\(lldb) frame variable --show-types --format c-string -- strings
 364            \\(root.strings.Strings) strings = {
 365            \\  ([*c]const u8) .c_ptr = "c_ptr\x07\x08\t"
 366            \\  ([*:0]const u8) .many_ptr = "many_ptr\n\x0b\x0c"
 367            \\  (*const [12:0]u8) .ptr_array = "ptr_array\x00\r\x1b"
 368            \\  ([:0]const u8) .slice = "slice\"\'\\\x00" len=9 {
 369            \\    (u8) [0] = "s"
 370            \\    (u8) [1] = "l"
 371            \\    (u8) [2] = "i"
 372            \\    (u8) [3] = "c"
 373            \\    (u8) [4] = "e"
 374            \\    (u8) [5] = "\""
 375            \\    (u8) [6] = "\'"
 376            \\    (u8) [7] = "\\"
 377            \\    (u8) [8] = "\x00"
 378            \\  }
 379            \\}
 380            \\(lldb) breakpoint delete --force 1
 381            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 382        },
 383    );
 384    db.addLldbTest(
 385        "enums",
 386        target,
 387        &.{
 388            .{
 389                .path = "enums.zig",
 390                .source =
 391                \\const Enums = struct {
 392                \\    const Zero = enum(u4) { _ };
 393                \\    const One = enum { first };
 394                \\    const Two = enum(i32) { first, second, _ };
 395                \\    const Three = enum { first, second, third };
 396                \\
 397                \\    zero: Zero = @enumFromInt(13),
 398                \\    one: One = .first,
 399                \\    two: Two = @enumFromInt(-1234),
 400                \\    three: Three = .second,
 401                \\};
 402                \\fn testEnums(enums: Enums) void {
 403                \\    _ = enums;
 404                \\}
 405                \\pub fn main() void {
 406                \\    testEnums(.{});
 407                \\}
 408                \\
 409                ,
 410            },
 411        },
 412        \\breakpoint set --file enums.zig --source-pattern-regexp '_ = enums;'
 413        \\process launch
 414        \\expression --show-types -- Enums
 415        \\frame variable --show-types -- enums
 416        \\breakpoint delete --force 1
 417    ,
 418        &.{
 419            \\(lldb) expression --show-types -- Enums
 420            \\(type) Enums = struct {
 421            \\  (type) Zero = enum {}
 422            \\  (type) One = enum {
 423            \\    (root.enums.Enums.One) first = .first
 424            \\  }
 425            \\  (type) Two = enum {
 426            \\    (root.enums.Enums.Two) first = .first
 427            \\    (root.enums.Enums.Two) second = .second
 428            \\  }
 429            \\  (type) Three = enum {
 430            \\    (root.enums.Enums.Three) first = .first
 431            \\    (root.enums.Enums.Three) second = .second
 432            \\    (root.enums.Enums.Three) third = .third
 433            \\  }
 434            \\}
 435            \\(lldb) frame variable --show-types -- enums
 436            \\(root.enums.Enums) enums = {
 437            \\  (root.enums.Enums.Zero) .zero = @enumFromInt(13)
 438            \\  (root.enums.Enums.One) .one = .first
 439            \\  (root.enums.Enums.Two) .two = @enumFromInt(-1234)
 440            \\  (root.enums.Enums.Three) .three = .second
 441            \\}
 442            \\(lldb) breakpoint delete --force 1
 443            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 444        },
 445    );
 446    db.addLldbTest(
 447        "errors",
 448        target,
 449        &.{
 450            .{
 451                .path = "errors.zig",
 452                .source =
 453                \\const Errors = struct {
 454                \\    const Zero = error{};
 455                \\    const One = Zero || error{One};
 456                \\    const Two = One || error{Two};
 457                \\    const Three = Two || error{Three};
 458                \\
 459                \\    one: One = error.One,
 460                \\    two: Two = error.Two,
 461                \\    three: Three = error.Three,
 462                \\    any: anyerror = error.Any,
 463                \\    any_void: anyerror!void = error.NotVoid,
 464                \\    any_u32: One!u32 = 42,
 465                \\};
 466                \\fn testErrors(errors: Errors) void {
 467                \\    _ = errors;
 468                \\}
 469                \\pub fn main() void {
 470                \\    testErrors(.{});
 471                \\}
 472                \\
 473                ,
 474            },
 475        },
 476        \\breakpoint set --file errors.zig --source-pattern-regexp '_ = errors;'
 477        \\process launch
 478        \\expression --show-types -- Errors
 479        \\frame variable --show-types -- errors
 480        \\breakpoint delete --force 1
 481    ,
 482        &.{
 483            \\(lldb) expression --show-types -- Errors
 484            \\(type) Errors = struct {
 485            \\  (type) Zero = error {}
 486            \\  (type) One = error {
 487            \\    (error{One}) One = error.One
 488            \\  }
 489            \\  (type) Two = error {
 490            \\    (error{One,Two}) One = error.One
 491            \\    (error{One,Two}) Two = error.Two
 492            \\  }
 493            \\  (type) Three = error {
 494            \\    (error{One,Three,Two}) One = error.One
 495            \\    (error{One,Three,Two}) Two = error.Two
 496            \\    (error{One,Three,Two}) Three = error.Three
 497            \\  }
 498            \\}
 499            \\(lldb) frame variable --show-types -- errors
 500            \\(root.errors.Errors) errors = {
 501            \\  (error{One}) .one = error.One
 502            \\  (error{One,Two}) .two = error.Two
 503            \\  (error{One,Three,Two}) .three = error.Three
 504            \\  (anyerror) .any = error.Any
 505            \\  (anyerror!void) .any_void = {
 506            \\    (anyerror) .error = error.NotVoid
 507            \\  }
 508            \\  (error{One}!u32) .any_u32 = {
 509            \\    (u32) .value = 42
 510            \\  }
 511            \\}
 512            \\(lldb) breakpoint delete --force 1
 513            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 514        },
 515    );
 516    db.addLldbTest(
 517        "optionals",
 518        target,
 519        &.{
 520            .{
 521                .path = "optionals.zig",
 522                .source =
 523                \\pub fn main() void {
 524                \\    {
 525                \\        var null_u32: ?u32 = null;
 526                \\        var maybe_u32: ?u32 = null;
 527                \\        var nonnull_u32: ?u32 = 456;
 528                \\        null_u32 = null_u32;
 529                \\        maybe_u32 = 123;
 530                \\        nonnull_u32 = nonnull_u32;
 531                \\    }
 532                \\}
 533                \\
 534                ,
 535            },
 536        },
 537        \\breakpoint set --file optionals.zig --source-pattern-regexp 'maybe_u32 = 123;'
 538        \\process launch
 539        \\frame variable -- null_u32 maybe_u32 nonnull_u32
 540        \\breakpoint delete --force 1
 541        \\
 542        \\breakpoint set --file optionals.zig --source-pattern-regexp 'nonnull_u32 = nonnull_u32;'
 543        \\process continue
 544        \\frame variable --show-types -- null_u32 maybe_u32 nonnull_u32
 545        \\breakpoint delete --force 2
 546    ,
 547        &.{
 548            \\(lldb) frame variable -- null_u32 maybe_u32 nonnull_u32
 549            \\(?u32) null_u32 = null
 550            \\(?u32) maybe_u32 = null
 551            \\(?u32) nonnull_u32 = (nonnull_u32.? = 456)
 552            \\(lldb) breakpoint delete --force 1
 553            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 554            ,
 555            \\(lldb) frame variable --show-types -- null_u32 maybe_u32 nonnull_u32
 556            \\(?u32) null_u32 = null
 557            \\(?u32) maybe_u32 = {
 558            \\  (u32) maybe_u32.? = 123
 559            \\}
 560            \\(?u32) nonnull_u32 = {
 561            \\  (u32) nonnull_u32.? = 456
 562            \\}
 563            \\(lldb) breakpoint delete --force 2
 564            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 565        },
 566    );
 567    db.addLldbTest(
 568        "unions",
 569        target,
 570        &.{
 571            .{
 572                .path = "unions.zig",
 573                .source =
 574                \\const Unions = struct {
 575                \\    const Enum = enum { first, second, third };
 576                \\    const Untagged = extern union {
 577                \\        u32: u32,
 578                \\        i32: i32,
 579                \\        f32: f32,
 580                \\    };
 581                \\    const SafetyTagged = union {
 582                \\        void: void,
 583                \\        en: Enum,
 584                \\        eu: error{Error}!Enum,
 585                \\    };
 586                \\    const Tagged = union(enum) {
 587                \\        void: void,
 588                \\        en: Enum,
 589                \\        eu: error{Error}!Enum,
 590                \\    };
 591                \\
 592                \\    untagged: Untagged = .{ .f32 = -1.5 },
 593                \\    safety_tagged: SafetyTagged = .{ .en = .second },
 594                \\    tagged: Tagged = .{ .eu = error.Error },
 595                \\};
 596                \\fn testUnions(unions: Unions) void {
 597                \\    _ = unions;
 598                \\}
 599                \\pub fn main() void {
 600                \\    testUnions(.{});
 601                \\}
 602                \\
 603                ,
 604            },
 605        },
 606        \\breakpoint set --file unions.zig --source-pattern-regexp '_ = unions;'
 607        \\process launch
 608        \\expression --show-types -- Unions
 609        \\frame variable --show-types -- unions
 610        \\breakpoint delete --force 1
 611    ,
 612        &.{
 613            \\(lldb) expression --show-types -- Unions
 614            \\(type) Unions = struct {
 615            \\  (type) Untagged = union {}
 616            \\  (type) SafetyTagged = union(enum) {
 617            \\    (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) void = .void
 618            \\    (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) en = .en
 619            \\    (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) eu = .eu
 620            \\  }
 621            \\  (type) Enum = enum {
 622            \\    (root.unions.Unions.Enum) first = .first
 623            \\    (root.unions.Unions.Enum) second = .second
 624            \\    (root.unions.Unions.Enum) third = .third
 625            \\  }
 626            \\  (type) Tagged = union(enum) {
 627            \\    (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) void = .void
 628            \\    (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) en = .en
 629            \\    (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) eu = .eu
 630            \\  }
 631            \\}
 632            \\(lldb) frame variable --show-types -- unions
 633            \\(root.unions.Unions) unions = {
 634            \\  (root.unions.Unions.Untagged) .untagged = {
 635            \\    (u32) .u32 = 3217031168
 636            \\    (i32) .i32 = -1077936128
 637            \\    (f32) .f32 = -1.5
 638            \\  }
 639            \\  (root.unions.Unions.SafetyTagged) .safety_tagged = {
 640            \\    (root.unions.Unions.Enum) .en = .second
 641            \\  }
 642            \\  (root.unions.Unions.Tagged) .tagged = {
 643            \\    (error{Error}!root.unions.Unions.Enum) .eu = {
 644            \\      (error{Error}) .error = error.Error
 645            \\    }
 646            \\  }
 647            \\}
 648            \\(lldb) breakpoint delete --force 1
 649            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 650        },
 651    );
 652    db.addLldbTest(
 653        "storage",
 654        target,
 655        &.{
 656            .{
 657                .path = "storage.zig",
 658                .source =
 659                \\comptime {
 660                \\    _ = @import("externs.zig");
 661                \\}
 662                \\const global_const: u64 = 0x19e50dc8d6002077;
 663                \\var global_var: u64 = 0xcc423cec08622e32;
 664                \\threadlocal var global_threadlocal1: u64 = 0xb4d643528c042121;
 665                \\threadlocal var global_threadlocal2: u64 = 0x43faea1cf5ad7a22;
 666                \\extern const extern_const: u64;
 667                \\extern var extern_var: u64;
 668                \\extern threadlocal var extern_threadlocal1: u64;
 669                \\extern threadlocal var extern_threadlocal2: u64;
 670                \\fn testStorage(
 671                \\    param1: u64,
 672                \\    param2: u64,
 673                \\    param3: u64,
 674                \\    param4: u64,
 675                \\    param5: u64,
 676                \\    param6: u64,
 677                \\    param7: u64,
 678                \\    param8: u64,
 679                \\) callconv(.c) void {
 680                \\    const local_comptime_val: u64 = global_const *% global_const;
 681                \\    const local_comptime_ptr: struct { u64 } = .{ local_comptime_val *% local_comptime_val };
 682                \\    const local_const: u64 = global_var ^ global_threadlocal1 ^ global_threadlocal2 ^
 683                \\        extern_const ^ extern_var ^ extern_threadlocal1 ^ extern_threadlocal2 ^
 684                \\        param1 ^ param2 ^ param3 ^ param4 ^ param5 ^ param6 ^ param7 ^ param8;
 685                \\    var local_var: u64 = local_comptime_ptr[0] ^ local_const;
 686                \\    local_var = local_var;
 687                \\}
 688                \\pub fn main() void {
 689                \\    testStorage(
 690                \\        0x6a607e08125c7e00,
 691                \\        0x98944cb2a45a8b51,
 692                \\        0xa320cf10601ee6fb,
 693                \\        0x691ed3535bad3274,
 694                \\        0x63690e6867a5799f,
 695                \\        0x8e163f0ec76067f2,
 696                \\        0xf9a252c455fb4c06,
 697                \\        0xc88533722601e481,
 698                \\    );
 699                \\}
 700                \\
 701                ,
 702            },
 703            .{
 704                .path = "externs.zig",
 705                .source =
 706                \\export const extern_const: u64 = 0x1b0c91ea0470b0b2;
 707                \\export var extern_var: u64 = 0x19bc17b3f0b61ebc;
 708                \\export threadlocal var extern_threadlocal1: u64 = 0x3034c4ce967ed64d;
 709                \\export threadlocal var extern_threadlocal2: u64 = 0xfd330ab00b4bc5eb;
 710                \\
 711                ,
 712            },
 713        },
 714        \\breakpoint set --file storage.zig --source-pattern-regexp 'local_var = local_var;'
 715        \\process launch
 716        \\target variable --show-types --format hex -- global_const global_var global_threadlocal1 global_threadlocal2 extern_const extern_var extern_threadlocal1 extern_threadlocal2
 717        \\frame variable --show-types --format hex -- param1 param2 param3 param4 param5 param6 param7 param8 local_comptime_val local_comptime_ptr.0 local_const local_var
 718        \\breakpoint delete --force 1
 719    ,
 720        &.{
 721            \\(lldb) target variable --show-types --format hex -- global_const global_var global_threadlocal1 global_threadlocal2 extern_const extern_var extern_threadlocal1 extern_threadlocal2
 722            \\(u64) global_const = 0x19e50dc8d6002077
 723            \\(u64) global_var = 0xcc423cec08622e32
 724            \\(u64) global_threadlocal1 = 0xb4d643528c042121
 725            \\(u64) global_threadlocal2 = 0x43faea1cf5ad7a22
 726            \\(u64) extern_const = 0x1b0c91ea0470b0b2
 727            \\(u64) extern_const = 0x1b0c91ea0470b0b2
 728            \\(u64) extern_var = 0x19bc17b3f0b61ebc
 729            \\(u64) extern_var = 0x19bc17b3f0b61ebc
 730            \\(u64) extern_threadlocal1 = 0x3034c4ce967ed64d
 731            \\(u64) extern_threadlocal1 = 0x3034c4ce967ed64d
 732            \\(u64) extern_threadlocal2 = 0xfd330ab00b4bc5eb
 733            \\(u64) extern_threadlocal2 = 0xfd330ab00b4bc5eb
 734            \\(lldb) frame variable --show-types --format hex -- param1 param2 param3 param4 param5 param6 param7 param8 local_comptime_val local_comptime_ptr.0 local_const local_var
 735            \\(u64) param1 = 0x6a607e08125c7e00
 736            \\(u64) param2 = 0x98944cb2a45a8b51
 737            \\(u64) param3 = 0xa320cf10601ee6fb
 738            \\(u64) param4 = 0x691ed3535bad3274
 739            \\(u64) param5 = 0x63690e6867a5799f
 740            \\(u64) param6 = 0x8e163f0ec76067f2
 741            \\(u64) param7 = 0xf9a252c455fb4c06
 742            \\(u64) param8 = 0xc88533722601e481
 743            \\(u64) local_comptime_val = 0x69490636f81df751
 744            \\(u64) local_comptime_ptr.0 = 0x82e834dae74767a1
 745            \\(u64) local_const = 0x104ba3ac46b25fad
 746            \\(u64) local_var = 0x92a39776a1f5380c
 747            \\(lldb) breakpoint delete --force 1
 748            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 749        },
 750    );
 751    db.addLldbTest(
 752        "if_blocks",
 753        target,
 754        &.{
 755            .{
 756                .path = "if_blocks.zig",
 757                .source =
 758                \\pub fn main() void {
 759                \\    for (0..2) |i| {
 760                \\        if (i == 0) {
 761                \\            var x: u32 = 123;
 762                \\            _ = &x;
 763                \\        } else {
 764                \\            var x: f32 = 4.5;
 765                \\            _ = &x;
 766                \\        }
 767                \\    }
 768                \\}
 769                \\
 770                ,
 771            },
 772        },
 773        \\breakpoint set --file if_blocks.zig --source-pattern-regexp '_ = &x;'
 774        \\process launch
 775        \\frame variable
 776        \\process continue
 777        \\frame variable
 778        \\breakpoint delete --force 1
 779    ,
 780        &.{
 781            \\(lldb) frame variable
 782            \\(usize) i = 0
 783            \\(u32) x = 123
 784            \\(lldb) process continue
 785            ,
 786            \\(lldb) frame variable
 787            \\(usize) i = 1
 788            \\(f32) x = 4.5
 789            \\(lldb) breakpoint delete --force 1
 790            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 791        },
 792    );
 793    db.addLldbTest(
 794        "switch_blocks",
 795        target,
 796        &.{
 797            .{
 798                .path = "switch_blocks.zig",
 799                .source =
 800                \\pub fn main() void {
 801                \\    for (0..2) |i| {
 802                \\        switch (i) {
 803                \\            0 => {
 804                \\                var x: u32 = 123;
 805                \\                _ = &x;
 806                \\            },
 807                \\            else => {
 808                \\                var x: f32 = 4.5;
 809                \\                _ = &x;
 810                \\            },
 811                \\        }
 812                \\    }
 813                \\}
 814                \\
 815                ,
 816            },
 817        },
 818        \\breakpoint set --file switch_blocks.zig --source-pattern-regexp '_ = &x;'
 819        \\process launch
 820        \\frame variable
 821        \\process continue
 822        \\frame variable
 823        \\breakpoint delete --force 1
 824    ,
 825        &.{
 826            \\(lldb) frame variable
 827            \\(usize) i = 0
 828            \\(u32) x = 123
 829            \\(lldb) process continue
 830            ,
 831            \\(lldb) frame variable
 832            \\(usize) i = 1
 833            \\(f32) x = 4.5
 834            \\(lldb) breakpoint delete --force 1
 835            \\1 breakpoints deleted; 0 breakpoint locations disabled.
 836        },
 837    );
 838    db.addLldbTest(
 839        "step_single_stmt_loops",
 840        target,
 841        &.{
 842            .{
 843                .path = "step_single_stmt_loops.zig",
 844                .source =
 845                \\pub fn main() void {
 846                \\    var x: u32 = 0;
 847                \\    for (0..3) |_| {
 848                \\        x +%= 1;
 849                \\    }
 850                \\    {
 851                \\        var i: u32 = 0;
 852                \\        while (i < 3) : (i +%= 1) {
 853                \\            x +%= 1;
 854                \\        }
 855                \\    }
 856                \\    {
 857                \\        var i: u32 = 0;
 858                \\        while (i < 3) {
 859                \\            i +%= 1;
 860                \\        }
 861                \\    }
 862                \\    inline for (0..3) |_| {
 863                \\        x +%= 1;
 864                \\    }
 865                \\    {
 866                \\        comptime var i: u32 = 0;
 867                \\        inline while (i < 3) : (i +%= 1) {
 868                \\            x +%= 1;
 869                \\        }
 870                \\    }
 871                \\    {
 872                \\        comptime var i: u32 = 0;
 873                \\        inline while (i < 3) {
 874                \\            i +%= 1;
 875                \\        }
 876                \\    }
 877                \\    x +%= 1;
 878                \\}
 879                \\
 880                ,
 881            },
 882        },
 883        \\breakpoint set --name step_single_stmt_loops.main
 884        \\process launch
 885        \\thread step-in
 886        \\#00
 887        \\frame variable x
 888        \\thread step-in
 889        \\#01
 890        \\frame variable x
 891        \\thread step-in
 892        \\#02
 893        \\frame variable x
 894        \\thread step-in
 895        \\#03
 896        \\frame variable x
 897        \\thread step-in
 898        \\#04
 899        \\frame variable x
 900        \\thread step-in
 901        \\#05
 902        \\frame variable x
 903        \\thread step-in
 904        \\#06
 905        \\frame variable x
 906        \\thread step-in
 907        \\#07
 908        \\frame variable x
 909        \\thread step-in
 910        \\#08
 911        \\frame variable x
 912        \\thread step-in
 913        \\#09
 914        \\frame variable x
 915        \\thread step-in
 916        \\#10
 917        \\frame variable x
 918        \\thread step-in
 919        \\#11
 920        \\frame variable x
 921        \\thread step-in
 922        \\#12
 923        \\frame variable x
 924        \\thread step-in
 925        \\#13
 926        \\frame variable x
 927        \\thread step-in
 928        \\#14
 929        \\frame variable x
 930        \\thread step-in
 931        \\#15
 932        \\frame variable x
 933        \\thread step-in
 934        \\#16
 935        \\frame variable x
 936        \\thread step-in
 937        \\#17
 938        \\frame variable x
 939        \\thread step-in
 940        \\#18
 941        \\frame variable x
 942        \\thread step-in
 943        \\#19
 944        \\frame variable x
 945        \\thread step-in
 946        \\#20
 947        \\frame variable x
 948        \\thread step-in
 949        \\#21
 950        \\frame variable x
 951        \\thread step-in
 952        \\#22
 953        \\frame variable x
 954        \\thread step-in
 955        \\#23
 956        \\frame variable x
 957        \\thread step-in
 958        \\#24
 959        \\frame variable x
 960        \\thread step-in
 961        \\#25
 962        \\frame variable x
 963        \\thread step-in
 964        \\#26
 965        \\frame variable x
 966        \\thread step-in
 967        \\#27
 968        \\frame variable x
 969        \\thread step-in
 970        \\#28
 971        \\frame variable x
 972        \\thread step-in
 973        \\#29
 974        \\frame variable x
 975        \\thread step-in
 976        \\#30
 977        \\frame variable x
 978        \\thread step-in
 979        \\#31
 980        \\frame variable x
 981        \\thread step-in
 982        \\#32
 983        \\frame variable x
 984        \\thread step-in
 985        \\#33
 986        \\frame variable x
 987        \\thread step-in
 988        \\#34
 989        \\frame variable x
 990        \\thread step-in
 991        \\#35
 992        \\frame variable x
 993        \\thread step-in
 994        \\#36
 995        \\frame variable x
 996        \\thread step-in
 997        \\#37
 998        \\frame variable x
 999        \\thread step-in
1000        \\#38
1001        \\frame variable x
1002        \\thread step-in
1003        \\#39
1004        \\frame variable x
1005        \\thread step-in
1006        \\#40
1007        \\frame variable x
1008        \\thread step-in
1009        \\#41
1010        \\frame variable x
1011        \\thread step-in
1012        \\#42
1013        \\frame variable x
1014        \\thread step-in
1015        \\#43
1016        \\frame variable x
1017        \\thread step-in
1018        \\#44
1019        \\frame variable x
1020        \\thread step-in
1021        \\#45
1022        \\frame variable x
1023        \\
1024    ,
1025        &.{
1026            \\(lldb) #00
1027            \\(lldb) frame variable x
1028            \\(u32) x = 0
1029            \\(lldb) thread step-in
1030            ,
1031            \\(lldb) #01
1032            \\(lldb) frame variable x
1033            \\(u32) x = 0
1034            \\(lldb) thread step-in
1035            ,
1036            \\(lldb) #02
1037            \\(lldb) frame variable x
1038            \\(u32) x = 1
1039            \\(lldb) thread step-in
1040            ,
1041            \\(lldb) #03
1042            \\(lldb) frame variable x
1043            \\(u32) x = 1
1044            \\(lldb) thread step-in
1045            ,
1046            \\(lldb) #04
1047            \\(lldb) frame variable x
1048            \\(u32) x = 1
1049            \\(lldb) thread step-in
1050            ,
1051            \\(lldb) #05
1052            \\(lldb) frame variable x
1053            \\(u32) x = 2
1054            \\(lldb) thread step-in
1055            ,
1056            \\(lldb) #06
1057            \\(lldb) frame variable x
1058            \\(u32) x = 2
1059            \\(lldb) thread step-in
1060            ,
1061            \\(lldb) #07
1062            \\(lldb) frame variable x
1063            \\(u32) x = 2
1064            \\(lldb) thread step-in
1065            ,
1066            \\(lldb) #08
1067            \\(lldb) frame variable x
1068            \\(u32) x = 3
1069            \\(lldb) thread step-in
1070            ,
1071            \\(lldb) #09
1072            \\(lldb) frame variable x
1073            \\(u32) x = 3
1074            \\(lldb) thread step-in
1075            ,
1076            \\(lldb) #10
1077            \\(lldb) frame variable x
1078            \\(u32) x = 3
1079            \\(lldb) thread step-in
1080            ,
1081            \\(lldb) #11
1082            \\(lldb) frame variable x
1083            \\(u32) x = 3
1084            \\(lldb) thread step-in
1085            ,
1086            \\(lldb) #12
1087            \\(lldb) frame variable x
1088            \\(u32) x = 3
1089            \\(lldb) thread step-in
1090            ,
1091            \\(lldb) #13
1092            \\(lldb) frame variable x
1093            \\(u32) x = 4
1094            \\(lldb) thread step-in
1095            ,
1096            \\(lldb) #14
1097            \\(lldb) frame variable x
1098            \\(u32) x = 4
1099            \\(lldb) thread step-in
1100            ,
1101            \\(lldb) #15
1102            \\(lldb) frame variable x
1103            \\(u32) x = 4
1104            \\(lldb) thread step-in
1105            ,
1106            \\(lldb) #16
1107            \\(lldb) frame variable x
1108            \\(u32) x = 5
1109            \\(lldb) thread step-in
1110            ,
1111            \\(lldb) #17
1112            \\(lldb) frame variable x
1113            \\(u32) x = 5
1114            \\(lldb) thread step-in
1115            ,
1116            \\(lldb) #18
1117            \\(lldb) frame variable x
1118            \\(u32) x = 5
1119            \\(lldb) thread step-in
1120            ,
1121            \\(lldb) #19
1122            \\(lldb) frame variable x
1123            \\(u32) x = 6
1124            \\(lldb) thread step-in
1125            ,
1126            \\(lldb) #20
1127            \\(lldb) frame variable x
1128            \\(u32) x = 6
1129            \\(lldb) thread step-in
1130            ,
1131            \\(lldb) #21
1132            \\(lldb) frame variable x
1133            \\(u32) x = 6
1134            \\(lldb) thread step-in
1135            ,
1136            \\(lldb) #22
1137            \\(lldb) frame variable x
1138            \\(u32) x = 6
1139            \\(lldb) thread step-in
1140            ,
1141            \\(lldb) #23
1142            \\(lldb) frame variable x
1143            \\(u32) x = 6
1144            \\(lldb) thread step-in
1145            ,
1146            \\(lldb) #24
1147            \\(lldb) frame variable x
1148            \\(u32) x = 6
1149            \\(lldb) thread step-in
1150            ,
1151            \\(lldb) #25
1152            \\(lldb) frame variable x
1153            \\(u32) x = 6
1154            \\(lldb) thread step-in
1155            ,
1156            \\(lldb) #26
1157            \\(lldb) frame variable x
1158            \\(u32) x = 6
1159            \\(lldb) thread step-in
1160            ,
1161            \\(lldb) #27
1162            \\(lldb) frame variable x
1163            \\(u32) x = 6
1164            \\(lldb) thread step-in
1165            ,
1166            \\(lldb) #28
1167            \\(lldb) frame variable x
1168            \\(u32) x = 6
1169            \\(lldb) thread step-in
1170            ,
1171            \\(lldb) #29
1172            \\(lldb) frame variable x
1173            \\(u32) x = 6
1174            \\(lldb) thread step-in
1175            ,
1176            \\(lldb) #30
1177            \\(lldb) frame variable x
1178            \\(u32) x = 6
1179            \\(lldb) thread step-in
1180            ,
1181            \\(lldb) #31
1182            \\(lldb) frame variable x
1183            \\(u32) x = 6
1184            \\(lldb) thread step-in
1185            ,
1186            \\(lldb) #32
1187            \\(lldb) frame variable x
1188            \\(u32) x = 6
1189            \\(lldb) thread step-in
1190            ,
1191            \\(lldb) #33
1192            \\(lldb) frame variable x
1193            \\(u32) x = 7
1194            \\(lldb) thread step-in
1195            ,
1196            \\(lldb) #34
1197            \\(lldb) frame variable x
1198            \\(u32) x = 7
1199            \\(lldb) thread step-in
1200            ,
1201            \\(lldb) #35
1202            \\(lldb) frame variable x
1203            \\(u32) x = 8
1204            \\(lldb) thread step-in
1205            ,
1206            \\(lldb) #36
1207            \\(lldb) frame variable x
1208            \\(u32) x = 8
1209            \\(lldb) thread step-in
1210            ,
1211            \\(lldb) #37
1212            \\(lldb) frame variable x
1213            \\(u32) x = 9
1214            \\(lldb) thread step-in
1215            ,
1216            \\(lldb) #38
1217            \\(lldb) frame variable x
1218            \\(u32) x = 9
1219            \\(lldb) thread step-in
1220            ,
1221            \\(lldb) #39
1222            \\(lldb) frame variable x
1223            \\(u32) x = 10
1224            \\(lldb) thread step-in
1225            ,
1226            \\(lldb) #40
1227            \\(lldb) frame variable x
1228            \\(u32) x = 10
1229            \\(lldb) thread step-in
1230            ,
1231            \\(lldb) #41
1232            \\(lldb) frame variable x
1233            \\(u32) x = 11
1234            \\(lldb) thread step-in
1235            ,
1236            \\(lldb) #42
1237            \\(lldb) frame variable x
1238            \\(u32) x = 11
1239            \\(lldb) thread step-in
1240            ,
1241            \\(lldb) #43
1242            \\(lldb) frame variable x
1243            \\(u32) x = 12
1244            \\(lldb) thread step-in
1245            ,
1246            \\(lldb) #44
1247            \\(lldb) frame variable x
1248            \\(u32) x = 12
1249            \\(lldb) thread step-in
1250            ,
1251            \\(lldb) #45
1252            \\(lldb) frame variable x
1253            \\(u32) x = 12
1254        },
1255    );
1256    db.addLldbTest(
1257        "inline_call",
1258        target,
1259        &.{
1260            .{
1261                .path = "root0.zig",
1262                .source =
1263                \\const root0 = @This();
1264                \\pub const root1 = @import("root1.zig");
1265                \\const mod0 = @import("module");
1266                \\const mod1 = mod0.mod1;
1267                \\pub fn r0pf(r0pa: u32) void {
1268                \\    root0.r0cf(r0pa ^ 1);
1269                \\    root0.r0cfi(r0pa ^ 2);
1270                \\    root1.r1cf(r0pa ^ 3);
1271                \\    root1.r1cfi(r0pa ^ 4);
1272                \\    mod0.m0cf(r0pa ^ 5);
1273                \\    mod0.m0cfi(r0pa ^ 6);
1274                \\    mod1.m1cf(r0pa ^ 7);
1275                \\    mod1.m1cfi(r0pa ^ 8);
1276                \\}
1277                \\pub inline fn r0pfi(r0pai: u32) void {
1278                \\    root0.r0cf(r0pai ^ 1);
1279                \\    root0.r0cfi(r0pai ^ 2);
1280                \\    root1.r1cf(r0pai ^ 3);
1281                \\    root1.r1cfi(r0pai ^ 4);
1282                \\    mod0.m0cf(r0pai ^ 5);
1283                \\    mod0.m0cfi(r0pai ^ 6);
1284                \\    mod1.m1cf(r0pai ^ 7);
1285                \\    mod1.m1cfi(r0pai ^ 8);
1286                \\}
1287                \\pub fn r0cf(r0ca: u32) void {
1288                \\    var discard = r0ca;
1289                \\    _ = &discard;
1290                \\}
1291                \\pub inline fn r0cfi(r0cai: u32) void {
1292                \\    var discard = r0cai;
1293                \\    _ = &discard;
1294                \\}
1295                \\pub fn main() void {
1296                \\    root0.r0pf(12);
1297                \\    root0.r0pfi(23);
1298                \\    root1.r1pf(34);
1299                \\    root1.r1pfi(45);
1300                \\    mod0.m0pf(56);
1301                \\    mod0.m0pfi(67);
1302                \\    mod1.m1pf(78);
1303                \\    mod1.m1pfi(89);
1304                \\}
1305                \\
1306                ,
1307            },
1308            .{
1309                .path = "root1.zig",
1310                .source =
1311                \\const root0 = @import("root0.zig");
1312                \\const root1 = @This();
1313                \\const mod0 = @import("module");
1314                \\const mod1 = mod0.mod1;
1315                \\pub fn r1pf(r1pa: u32) void {
1316                \\    root0.r0cf(r1pa ^ 1);
1317                \\    root0.r0cfi(r1pa ^ 2);
1318                \\    root1.r1cf(r1pa ^ 3);
1319                \\    root1.r1cfi(r1pa ^ 4);
1320                \\    mod0.m0cf(r1pa ^ 5);
1321                \\    mod0.m0cfi(r1pa ^ 6);
1322                \\    mod1.m1cf(r1pa ^ 7);
1323                \\    mod1.m1cfi(r1pa ^ 8);
1324                \\}
1325                \\pub inline fn r1pfi(r1pai: u32) void {
1326                \\    root0.r0cf(r1pai ^ 1);
1327                \\    root0.r0cfi(r1pai ^ 2);
1328                \\    root1.r1cf(r1pai ^ 3);
1329                \\    root1.r1cfi(r1pai ^ 4);
1330                \\    mod0.m0cf(r1pai ^ 5);
1331                \\    mod0.m0cfi(r1pai ^ 6);
1332                \\    mod1.m1cf(r1pai ^ 7);
1333                \\    mod1.m1cfi(r1pai ^ 8);
1334                \\}
1335                \\pub fn r1cf(r1ca: u32) void {
1336                \\    var discard = r1ca;
1337                \\    _ = &discard;
1338                \\}
1339                \\pub inline fn r1cfi(r1cai: u32) void {
1340                \\    var discard = r1cai;
1341                \\    _ = &discard;
1342                \\}
1343                \\
1344                ,
1345            },
1346            .{
1347                .import = "module",
1348                .path = "mod0.zig",
1349                .source =
1350                \\const root0 = @import("root");
1351                \\const root1 = root0.root1;
1352                \\const mod0 = @This();
1353                \\pub const mod1 = @import("mod1.zig");
1354                \\pub fn m0pf(m0pa: u32) void {
1355                \\    root0.r0cf(m0pa ^ 1);
1356                \\    root0.r0cfi(m0pa ^ 2);
1357                \\    root1.r1cf(m0pa ^ 3);
1358                \\    root1.r1cfi(m0pa ^ 4);
1359                \\    mod0.m0cf(m0pa ^ 5);
1360                \\    mod0.m0cfi(m0pa ^ 6);
1361                \\    mod1.m1cf(m0pa ^ 7);
1362                \\    mod1.m1cfi(m0pa ^ 8);
1363                \\}
1364                \\pub inline fn m0pfi(m0pai: u32) void {
1365                \\    root0.r0cf(m0pai ^ 1);
1366                \\    root0.r0cfi(m0pai ^ 2);
1367                \\    root1.r1cf(m0pai ^ 3);
1368                \\    root1.r1cfi(m0pai ^ 4);
1369                \\    mod0.m0cf(m0pai ^ 5);
1370                \\    mod0.m0cfi(m0pai ^ 6);
1371                \\    mod1.m1cf(m0pai ^ 7);
1372                \\    mod1.m1cfi(m0pai ^ 8);
1373                \\}
1374                \\pub fn m0cf(m0ca: u32) void {
1375                \\    var discard = m0ca;
1376                \\    _ = &discard;
1377                \\}
1378                \\pub inline fn m0cfi(m0cai: u32) void {
1379                \\    var discard = m0cai;
1380                \\    _ = &discard;
1381                \\}
1382                \\
1383                ,
1384            },
1385            .{
1386                .path = "mod1.zig",
1387                .source =
1388                \\const root0 = @import("root");
1389                \\const root1 = root0.root1;
1390                \\const mod0 = @import("mod0.zig");
1391                \\const mod1 = @This();
1392                \\pub fn m1pf(m1pa: u32) void {
1393                \\    root0.r0cf(m1pa ^ 1);
1394                \\    root0.r0cfi(m1pa ^ 2);
1395                \\    root1.r1cf(m1pa ^ 3);
1396                \\    root1.r1cfi(m1pa ^ 4);
1397                \\    mod0.m0cf(m1pa ^ 5);
1398                \\    mod0.m0cfi(m1pa ^ 6);
1399                \\    mod1.m1cf(m1pa ^ 7);
1400                \\    mod1.m1cfi(m1pa ^ 8);
1401                \\}
1402                \\pub inline fn m1pfi(m1pai: u32) void {
1403                \\    root0.r0cf(m1pai ^ 1);
1404                \\    root0.r0cfi(m1pai ^ 2);
1405                \\    root1.r1cf(m1pai ^ 3);
1406                \\    root1.r1cfi(m1pai ^ 4);
1407                \\    mod0.m0cf(m1pai ^ 5);
1408                \\    mod0.m0cfi(m1pai ^ 6);
1409                \\    mod1.m1cf(m1pai ^ 7);
1410                \\    mod1.m1cfi(m1pai ^ 8);
1411                \\}
1412                \\pub fn m1cf(m1ca: u32) void {
1413                \\    var discard = m1ca;
1414                \\    _ = &discard;
1415                \\}
1416                \\pub inline fn m1cfi(m1cai: u32) void {
1417                \\    var discard = m1cai;
1418                \\    _ = &discard;
1419                \\}
1420                \\
1421                ,
1422            },
1423        },
1424        \\settings set frame-format 'frame #${frame.index}:{ ${module.file.basename}{\`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${line.file.basename}:${line.number}{:${line.column}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}\n'
1425        \\
1426        \\breakpoint set --file root0.zig --line 26
1427        \\breakpoint set --file root0.zig --line 30
1428        \\breakpoint set --file root1.zig --line 26
1429        \\breakpoint set --file root1.zig --line 30
1430        \\breakpoint set --file mod0.zig --line 26
1431        \\breakpoint set --file mod0.zig --line 30
1432        \\breakpoint set --file mod1.zig --line 26
1433        \\breakpoint set --file mod1.zig --line 30
1434        \\
1435        \\process launch
1436        \\thread backtrace --count 3
1437        \\process continue
1438        \\thread backtrace --count 3
1439        \\process continue
1440        \\thread backtrace --count 3
1441        \\process continue
1442        \\thread backtrace --count 3
1443        \\process continue
1444        \\thread backtrace --count 3
1445        \\process continue
1446        \\thread backtrace --count 3
1447        \\process continue
1448        \\thread backtrace --count 3
1449        \\process continue
1450        \\thread backtrace --count 3
1451        \\
1452        \\process continue
1453        \\thread backtrace --count 3
1454        \\process continue
1455        \\thread backtrace --count 3
1456        \\process continue
1457        \\thread backtrace --count 3
1458        \\process continue
1459        \\thread backtrace --count 3
1460        \\process continue
1461        \\thread backtrace --count 3
1462        \\process continue
1463        \\thread backtrace --count 3
1464        \\process continue
1465        \\thread backtrace --count 3
1466        \\process continue
1467        \\thread backtrace --count 3
1468        \\
1469        \\process continue
1470        \\thread backtrace --count 3
1471        \\process continue
1472        \\thread backtrace --count 3
1473        \\process continue
1474        \\thread backtrace --count 3
1475        \\process continue
1476        \\thread backtrace --count 3
1477        \\process continue
1478        \\thread backtrace --count 3
1479        \\process continue
1480        \\thread backtrace --count 3
1481        \\process continue
1482        \\thread backtrace --count 3
1483        \\process continue
1484        \\thread backtrace --count 3
1485        \\
1486        \\process continue
1487        \\thread backtrace --count 3
1488        \\process continue
1489        \\thread backtrace --count 3
1490        \\process continue
1491        \\thread backtrace --count 3
1492        \\process continue
1493        \\thread backtrace --count 3
1494        \\process continue
1495        \\thread backtrace --count 3
1496        \\process continue
1497        \\thread backtrace --count 3
1498        \\process continue
1499        \\thread backtrace --count 3
1500        \\process continue
1501        \\thread backtrace --count 3
1502        \\
1503        \\process continue
1504        \\thread backtrace --count 3
1505        \\process continue
1506        \\thread backtrace --count 3
1507        \\process continue
1508        \\thread backtrace --count 3
1509        \\process continue
1510        \\thread backtrace --count 3
1511        \\process continue
1512        \\thread backtrace --count 3
1513        \\process continue
1514        \\thread backtrace --count 3
1515        \\process continue
1516        \\thread backtrace --count 3
1517        \\process continue
1518        \\thread backtrace --count 3
1519        \\
1520        \\process continue
1521        \\thread backtrace --count 3
1522        \\process continue
1523        \\thread backtrace --count 3
1524        \\process continue
1525        \\thread backtrace --count 3
1526        \\process continue
1527        \\thread backtrace --count 3
1528        \\process continue
1529        \\thread backtrace --count 3
1530        \\process continue
1531        \\thread backtrace --count 3
1532        \\process continue
1533        \\thread backtrace --count 3
1534        \\process continue
1535        \\thread backtrace --count 3
1536        \\
1537        \\process continue
1538        \\thread backtrace --count 3
1539        \\process continue
1540        \\thread backtrace --count 3
1541        \\process continue
1542        \\thread backtrace --count 3
1543        \\process continue
1544        \\thread backtrace --count 3
1545        \\process continue
1546        \\thread backtrace --count 3
1547        \\process continue
1548        \\thread backtrace --count 3
1549        \\process continue
1550        \\thread backtrace --count 3
1551        \\process continue
1552        \\thread backtrace --count 3
1553        \\
1554        \\process continue
1555        \\thread backtrace --count 3
1556        \\process continue
1557        \\thread backtrace --count 3
1558        \\process continue
1559        \\thread backtrace --count 3
1560        \\process continue
1561        \\thread backtrace --count 3
1562        \\process continue
1563        \\thread backtrace --count 3
1564        \\process continue
1565        \\thread backtrace --count 3
1566        \\process continue
1567        \\thread backtrace --count 3
1568        \\process continue
1569        \\thread backtrace --count 3
1570    ,
1571        &.{
1572            \\  * frame #0: inline_call`root0.r0cf(r0ca=13) at root0.zig:26:5
1573            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:6:15
1574            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1575            ,
1576            \\  * frame #0: inline_call`root0.r0pf [inlined] r0cfi(r0cai=14) at root0.zig:30:5
1577            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:7:16
1578            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1579            ,
1580            \\  * frame #0: inline_call`root1.r1cf(r1ca=15) at root1.zig:26:5
1581            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:8:15
1582            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1583            ,
1584            \\  * frame #0: inline_call`root0.r0pf [inlined] r1cfi(r1cai=8) at root1.zig:30:5
1585            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:9:16
1586            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1587            ,
1588            \\  * frame #0: inline_call`mod0.m0cf(m0ca=9) at mod0.zig:26:5
1589            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:10:14
1590            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1591            ,
1592            \\  * frame #0: inline_call`root0.r0pf [inlined] m0cfi(m0cai=10) at mod0.zig:30:5
1593            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:11:15
1594            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1595            ,
1596            \\  * frame #0: inline_call`mod1.m1cf(m1ca=11) at mod1.zig:26:5
1597            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:12:14
1598            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1599            ,
1600            \\  * frame #0: inline_call`root0.r0pf [inlined] m1cfi(m1cai=4) at mod1.zig:30:5
1601            \\    frame #1: inline_call`root0.r0pf(r0pa=12) at root0.zig:13:15
1602            \\    frame #2: inline_call`root0.main at root0.zig:34:15
1603            ,
1604            \\  * frame #0: inline_call`root0.r0cf(r0ca=22) at root0.zig:26:5
1605            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:16:15
1606            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1607            ,
1608            \\  * frame #0: inline_call`root0.main [inlined] r0cfi(r0cai=21) at root0.zig:30:5
1609            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:17:16
1610            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1611            ,
1612            \\  * frame #0: inline_call`root1.r1cf(r1ca=20) at root1.zig:26:5
1613            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:18:15
1614            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1615            ,
1616            \\  * frame #0: inline_call`root0.main [inlined] r1cfi(r1cai=19) at root1.zig:30:5
1617            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:19:16
1618            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1619            ,
1620            \\  * frame #0: inline_call`mod0.m0cf(m0ca=18) at mod0.zig:26:5
1621            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:20:14
1622            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1623            ,
1624            \\  * frame #0: inline_call`root0.main [inlined] m0cfi(m0cai=17) at mod0.zig:30:5
1625            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:21:15
1626            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1627            ,
1628            \\  * frame #0: inline_call`mod1.m1cf(m1ca=16) at mod1.zig:26:5
1629            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:22:14
1630            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1631            ,
1632            \\  * frame #0: inline_call`root0.main [inlined] m1cfi(m1cai=31) at mod1.zig:30:5
1633            \\    frame #1: inline_call`root0.main [inlined] r0pfi(r0pai=23) at root0.zig:23:15
1634            \\    frame #2: inline_call`root0.main at root0.zig:35:16
1635            ,
1636            \\  * frame #0: inline_call`root0.r0cf(r0ca=35) at root0.zig:26:5
1637            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:6:15
1638            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1639            ,
1640            \\  * frame #0: inline_call`root1.r1pf [inlined] r0cfi(r0cai=32) at root0.zig:30:5
1641            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:7:16
1642            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1643            ,
1644            \\  * frame #0: inline_call`root1.r1cf(r1ca=33) at root1.zig:26:5
1645            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:8:15
1646            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1647            ,
1648            \\  * frame #0: inline_call`root1.r1pf [inlined] r1cfi(r1cai=38) at root1.zig:30:5
1649            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:9:16
1650            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1651            ,
1652            \\  * frame #0: inline_call`mod0.m0cf(m0ca=39) at mod0.zig:26:5
1653            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:10:14
1654            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1655            ,
1656            \\  * frame #0: inline_call`root1.r1pf [inlined] m0cfi(m0cai=36) at mod0.zig:30:5
1657            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:11:15
1658            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1659            ,
1660            \\  * frame #0: inline_call`mod1.m1cf(m1ca=37) at mod1.zig:26:5
1661            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:12:14
1662            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1663            ,
1664            \\  * frame #0: inline_call`root1.r1pf [inlined] m1cfi(m1cai=42) at mod1.zig:30:5
1665            \\    frame #1: inline_call`root1.r1pf(r1pa=34) at root1.zig:13:15
1666            \\    frame #2: inline_call`root0.main at root0.zig:36:15
1667            ,
1668            \\  * frame #0: inline_call`root0.r0cf(r0ca=44) at root0.zig:26:5
1669            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:16:15
1670            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1671            ,
1672            \\  * frame #0: inline_call`root0.main [inlined] r0cfi(r0cai=47) at root0.zig:30:5
1673            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:17:16
1674            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1675            ,
1676            \\  * frame #0: inline_call`root1.r1cf(r1ca=46) at root1.zig:26:5
1677            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:18:15
1678            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1679            ,
1680            \\  * frame #0: inline_call`root0.main [inlined] r1cfi(r1cai=41) at root1.zig:30:5
1681            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:19:16
1682            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1683            ,
1684            \\  * frame #0: inline_call`mod0.m0cf(m0ca=40) at mod0.zig:26:5
1685            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:20:14
1686            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1687            ,
1688            \\  * frame #0: inline_call`root0.main [inlined] m0cfi(m0cai=43) at mod0.zig:30:5
1689            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:21:15
1690            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1691            ,
1692            \\  * frame #0: inline_call`mod1.m1cf(m1ca=42) at mod1.zig:26:5
1693            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:22:14
1694            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1695            ,
1696            \\  * frame #0: inline_call`root0.main [inlined] m1cfi(m1cai=37) at mod1.zig:30:5
1697            \\    frame #1: inline_call`root0.main [inlined] r1pfi(r1pai=45) at root1.zig:23:15
1698            \\    frame #2: inline_call`root0.main at root0.zig:37:16
1699            ,
1700            \\  * frame #0: inline_call`root0.r0cf(r0ca=57) at root0.zig:26:5
1701            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:6:15
1702            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1703            ,
1704            \\  * frame #0: inline_call`mod0.m0pf [inlined] r0cfi(r0cai=58) at root0.zig:30:5
1705            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:7:16
1706            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1707            ,
1708            \\  * frame #0: inline_call`root1.r1cf(r1ca=59) at root1.zig:26:5
1709            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:8:15
1710            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1711            ,
1712            \\  * frame #0: inline_call`mod0.m0pf [inlined] r1cfi(r1cai=60) at root1.zig:30:5
1713            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:9:16
1714            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1715            ,
1716            \\  * frame #0: inline_call`mod0.m0cf(m0ca=61) at mod0.zig:26:5
1717            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:10:14
1718            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1719            ,
1720            \\  * frame #0: inline_call`mod0.m0pf [inlined] m0cfi(m0cai=62) at mod0.zig:30:5
1721            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:11:15
1722            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1723            ,
1724            \\  * frame #0: inline_call`mod1.m1cf(m1ca=63) at mod1.zig:26:5
1725            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:12:14
1726            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1727            ,
1728            \\  * frame #0: inline_call`mod0.m0pf [inlined] m1cfi(m1cai=48) at mod1.zig:30:5
1729            \\    frame #1: inline_call`mod0.m0pf(m0pa=56) at mod0.zig:13:15
1730            \\    frame #2: inline_call`root0.main at root0.zig:38:14
1731            ,
1732            \\  * frame #0: inline_call`root0.r0cf(r0ca=66) at root0.zig:26:5
1733            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:16:15
1734            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1735            ,
1736            \\  * frame #0: inline_call`root0.main [inlined] r0cfi(r0cai=65) at root0.zig:30:5
1737            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:17:16
1738            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1739            ,
1740            \\  * frame #0: inline_call`root1.r1cf(r1ca=64) at root1.zig:26:5
1741            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:18:15
1742            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1743            ,
1744            \\  * frame #0: inline_call`root0.main [inlined] r1cfi(r1cai=71) at root1.zig:30:5
1745            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:19:16
1746            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1747            ,
1748            \\  * frame #0: inline_call`mod0.m0cf(m0ca=70) at mod0.zig:26:5
1749            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:20:14
1750            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1751            ,
1752            \\  * frame #0: inline_call`root0.main [inlined] m0cfi(m0cai=69) at mod0.zig:30:5
1753            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:21:15
1754            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1755            ,
1756            \\  * frame #0: inline_call`mod1.m1cf(m1ca=68) at mod1.zig:26:5
1757            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:22:14
1758            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1759            ,
1760            \\  * frame #0: inline_call`root0.main [inlined] m1cfi(m1cai=75) at mod1.zig:30:5
1761            \\    frame #1: inline_call`root0.main [inlined] m0pfi(m0pai=67) at mod0.zig:23:15
1762            \\    frame #2: inline_call`root0.main at root0.zig:39:15
1763            ,
1764            \\  * frame #0: inline_call`root0.r0cf(r0ca=79) at root0.zig:26:5
1765            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:6:15
1766            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1767            ,
1768            \\  * frame #0: inline_call`mod1.m1pf [inlined] r0cfi(r0cai=76) at root0.zig:30:5
1769            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:7:16
1770            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1771            ,
1772            \\  * frame #0: inline_call`root1.r1cf(r1ca=77) at root1.zig:26:5
1773            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:8:15
1774            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1775            ,
1776            \\  * frame #0: inline_call`mod1.m1pf [inlined] r1cfi(r1cai=74) at root1.zig:30:5
1777            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:9:16
1778            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1779            ,
1780            \\  * frame #0: inline_call`mod0.m0cf(m0ca=75) at mod0.zig:26:5
1781            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:10:14
1782            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1783            ,
1784            \\  * frame #0: inline_call`mod1.m1pf [inlined] m0cfi(m0cai=72) at mod0.zig:30:5
1785            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:11:15
1786            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1787            ,
1788            \\  * frame #0: inline_call`mod1.m1cf(m1ca=73) at mod1.zig:26:5
1789            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:12:14
1790            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1791            ,
1792            \\  * frame #0: inline_call`mod1.m1pf [inlined] m1cfi(m1cai=70) at mod1.zig:30:5
1793            \\    frame #1: inline_call`mod1.m1pf(m1pa=78) at mod1.zig:13:15
1794            \\    frame #2: inline_call`root0.main at root0.zig:40:14
1795            ,
1796            \\  * frame #0: inline_call`root0.r0cf(r0ca=88) at root0.zig:26:5
1797            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:16:15
1798            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1799            ,
1800            \\  * frame #0: inline_call`root0.main [inlined] r0cfi(r0cai=91) at root0.zig:30:5
1801            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:17:16
1802            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1803            ,
1804            \\  * frame #0: inline_call`root1.r1cf(r1ca=90) at root1.zig:26:5
1805            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:18:15
1806            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1807            ,
1808            \\  * frame #0: inline_call`root0.main [inlined] r1cfi(r1cai=93) at root1.zig:30:5
1809            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:19:16
1810            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1811            ,
1812            \\  * frame #0: inline_call`mod0.m0cf(m0ca=92) at mod0.zig:26:5
1813            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:20:14
1814            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1815            ,
1816            \\  * frame #0: inline_call`root0.main [inlined] m0cfi(m0cai=95) at mod0.zig:30:5
1817            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:21:15
1818            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1819            ,
1820            \\  * frame #0: inline_call`mod1.m1cf(m1ca=94) at mod1.zig:26:5
1821            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:22:14
1822            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1823            ,
1824            \\  * frame #0: inline_call`root0.main [inlined] m1cfi(m1cai=81) at mod1.zig:30:5
1825            \\    frame #1: inline_call`root0.main [inlined] m1pfi(m1pai=89) at mod1.zig:23:15
1826            \\    frame #2: inline_call`root0.main at root0.zig:41:15
1827        },
1828    );
1829    db.addLldbTest(
1830        "link_object",
1831        target,
1832        &.{
1833            .{
1834                .path = "main.zig",
1835                .source =
1836                \\extern fn fabsf(f32) f32;
1837                \\pub fn main() void {
1838                \\    var x: f32 = -1234.5;
1839                \\    x = fabsf(x);
1840                \\    _ = &x;
1841                \\}
1842                \\
1843                ,
1844            },
1845        },
1846        \\breakpoint set --file main.zig --source-pattern-regexp 'x = fabsf\(x\);'
1847        \\process launch
1848        \\frame variable -- x
1849        \\breakpoint delete --force 1
1850        \\
1851        \\breakpoint set --file main.zig --source-pattern-regexp '_ = &x;'
1852        \\process continue
1853        \\frame variable -- x
1854        \\breakpoint delete --force 2
1855    ,
1856        &.{
1857            \\(lldb) frame variable -- x
1858            \\(f32) x = -1234.5
1859            \\(lldb) breakpoint delete --force 1
1860            \\1 breakpoints deleted; 0 breakpoint locations disabled.
1861            ,
1862            \\(lldb) frame variable -- x
1863            \\(f32) x = 1234.5
1864            \\(lldb) breakpoint delete --force 2
1865            \\1 breakpoints deleted; 0 breakpoint locations disabled.
1866        },
1867    );
1868    db.addLldbTest(
1869        "hash_map",
1870        target,
1871        &.{
1872            .{
1873                .path = "main.zig",
1874                .source =
1875                \\const std = @import("std");
1876                \\const Context = struct {
1877                \\    pub fn hash(_: Context, key: u32) Map.Hash {
1878                \\        return key;
1879                \\    }
1880                \\    pub fn eql(_: Context, lhs: u32, rhs: u32) bool {
1881                \\        return lhs == rhs;
1882                \\    }
1883                \\};
1884                \\const Map = std.HashMap(u32, u32, Context, 63);
1885                \\fn testHashMap(map: Map) void {
1886                \\    _ = map;
1887                \\}
1888                \\pub fn main() !void {
1889                \\    var map = Map.init(std.heap.page_allocator);
1890                \\    defer map.deinit();
1891                \\    try map.ensureTotalCapacity(10);
1892                \\    map.putAssumeCapacity(0, 1);
1893                \\    map.putAssumeCapacity(2, 3);
1894                \\    map.putAssumeCapacity(4, 5);
1895                \\    map.putAssumeCapacity(6, 7);
1896                \\    map.putAssumeCapacity(8, 9);
1897                \\
1898                \\    testHashMap(map);
1899                \\}
1900                \\
1901                ,
1902            },
1903        },
1904        \\breakpoint set --file main.zig --source-pattern-regexp '_ = map;'
1905        \\process launch
1906        \\frame variable --show-types -- map.unmanaged
1907        \\breakpoint delete --force 1
1908    ,
1909        &.{
1910            \\(lldb) frame variable --show-types -- map.unmanaged
1911            \\(std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63)) map.unmanaged = len=5 capacity=16 {
1912            \\  (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [0] = {
1913            \\    (u32) .key = 0
1914            \\    (u32) .value = 1
1915            \\  }
1916            \\  (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [1] = {
1917            \\    (u32) .key = 2
1918            \\    (u32) .value = 3
1919            \\  }
1920            \\  (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [2] = {
1921            \\    (u32) .key = 4
1922            \\    (u32) .value = 5
1923            \\  }
1924            \\  (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [3] = {
1925            \\    (u32) .key = 6
1926            \\    (u32) .value = 7
1927            \\  }
1928            \\  (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [4] = {
1929            \\    (u32) .key = 8
1930            \\    (u32) .value = 9
1931            \\  }
1932            \\}
1933            \\(lldb) breakpoint delete --force 1
1934            \\1 breakpoints deleted; 0 breakpoint locations disabled.
1935        },
1936    );
1937    db.addLldbTest(
1938        "multi_array_list",
1939        target,
1940        &.{
1941            .{
1942                .path = "main.zig",
1943                .source =
1944                \\const std = @import("std");
1945                \\const Elem0 = struct { u32, u8, u16 };
1946                \\const Elem1 = struct { a: u32, b: u8, c: u16 };
1947                \\fn testMultiArrayList(
1948                \\    list0: std.MultiArrayList(Elem0),
1949                \\    slice0: std.MultiArrayList(Elem0).Slice,
1950                \\    list1: std.MultiArrayList(Elem1),
1951                \\    slice1: std.MultiArrayList(Elem1).Slice,
1952                \\) void {
1953                \\    _ = .{ list0, slice0, list1, slice1 };
1954                \\}
1955                \\pub fn main() !void {
1956                \\    var list0: std.MultiArrayList(Elem0) = .{};
1957                \\    defer list0.deinit(std.heap.page_allocator);
1958                \\    try list0.setCapacity(std.heap.page_allocator, 8);
1959                \\    list0.appendAssumeCapacity(.{ 1, 2, 3 });
1960                \\    list0.appendAssumeCapacity(.{ 4, 5, 6 });
1961                \\    list0.appendAssumeCapacity(.{ 7, 8, 9 });
1962                \\    const slice0 = list0.slice();
1963                \\
1964                \\    var list1: std.MultiArrayList(Elem1) = .{};
1965                \\    defer list1.deinit(std.heap.page_allocator);
1966                \\    try list1.setCapacity(std.heap.page_allocator, 12);
1967                \\    list1.appendAssumeCapacity(.{ .a = 1, .b = 2, .c = 3 });
1968                \\    list1.appendAssumeCapacity(.{ .a = 4, .b = 5, .c = 6 });
1969                \\    list1.appendAssumeCapacity(.{ .a = 7, .b = 8, .c = 9 });
1970                \\    const slice1 = list1.slice();
1971                \\
1972                \\    testMultiArrayList(list0, slice0, list1, slice1);
1973                \\}
1974                \\
1975                ,
1976            },
1977        },
1978        \\breakpoint set --file main.zig --source-pattern-regexp '_ = \.{ list0, slice0, list1, slice1 };'
1979        \\process launch
1980        \\frame variable --show-types -- list0 list0.len list0.capacity list0[0] list0[1] list0[2] list0.0 list0.1 list0.2
1981        \\frame variable --show-types -- slice0 slice0.len slice0.capacity slice0[0] slice0[1] slice0[2] slice0.0 slice0.1 slice0.2
1982        \\frame variable --show-types -- list1 list1.len list1.capacity list1[0] list1[1] list1[2] list1.a list1.b list1.c
1983        \\frame variable --show-types -- slice1 slice1.len slice1.capacity slice1[0] slice1[1] slice1[2] slice1.a slice1.b slice1.c
1984        \\breakpoint delete --force 1
1985    ,
1986        &.{
1987            \\(lldb) frame variable --show-types -- list0 list0.len list0.capacity list0[0] list0[1] list0[2] list0.0 list0.1 list0.2
1988            \\(std.multi_array_list.MultiArrayList(struct { u32, u8, u16 })) list0 = len=3 capacity=8 {
1989            \\  (struct { u32, u8, u16 }) [0] = {
1990            \\    (u32) .@"0" = 1
1991            \\    (u8) .@"1" = 2
1992            \\    (u16) .@"2" = 3
1993            \\  }
1994            \\  (struct { u32, u8, u16 }) [1] = {
1995            \\    (u32) .@"0" = 4
1996            \\    (u8) .@"1" = 5
1997            \\    (u16) .@"2" = 6
1998            \\  }
1999            \\  (struct { u32, u8, u16 }) [2] = {
2000            \\    (u32) .@"0" = 7
2001            \\    (u8) .@"1" = 8
2002            \\    (u16) .@"2" = 9
2003            \\  }
2004            \\}
2005            \\(usize) list0.len = 3
2006            \\(usize) list0.capacity = 8
2007            \\(struct { u32, u8, u16 }) list0[0] = {
2008            \\  (u32) .@"0" = 1
2009            \\  (u8) .@"1" = 2
2010            \\  (u16) .@"2" = 3
2011            \\}
2012            \\(struct { u32, u8, u16 }) list0[1] = {
2013            \\  (u32) .@"0" = 4
2014            \\  (u8) .@"1" = 5
2015            \\  (u16) .@"2" = 6
2016            \\}
2017            \\(struct { u32, u8, u16 }) list0[2] = {
2018            \\  (u32) .@"0" = 7
2019            \\  (u8) .@"1" = 8
2020            \\  (u16) .@"2" = 9
2021            \\}
2022            \\([3]u32) list0.0 = {
2023            \\  (u32) [0] = 1
2024            \\  (u32) [1] = 4
2025            \\  (u32) [2] = 7
2026            \\}
2027            \\([3]u8) list0.1 = {
2028            \\  (u8) [0] = 2
2029            \\  (u8) [1] = 5
2030            \\  (u8) [2] = 8
2031            \\}
2032            \\([3]u16) list0.2 = {
2033            \\  (u16) [0] = 3
2034            \\  (u16) [1] = 6
2035            \\  (u16) [2] = 9
2036            \\}
2037            \\(lldb) frame variable --show-types -- slice0 slice0.len slice0.capacity slice0[0] slice0[1] slice0[2] slice0.0 slice0.1 slice0.2
2038            \\(std.multi_array_list.MultiArrayList(struct { u32, u8, u16 }).Slice) slice0 = len=3 capacity=8 {
2039            \\  (struct { u32, u8, u16 }) [0] = {
2040            \\    (u32) .@"0" = 1
2041            \\    (u8) .@"1" = 2
2042            \\    (u16) .@"2" = 3
2043            \\  }
2044            \\  (struct { u32, u8, u16 }) [1] = {
2045            \\    (u32) .@"0" = 4
2046            \\    (u8) .@"1" = 5
2047            \\    (u16) .@"2" = 6
2048            \\  }
2049            \\  (struct { u32, u8, u16 }) [2] = {
2050            \\    (u32) .@"0" = 7
2051            \\    (u8) .@"1" = 8
2052            \\    (u16) .@"2" = 9
2053            \\  }
2054            \\}
2055            \\(usize) slice0.len = 3
2056            \\(usize) slice0.capacity = 8
2057            \\(struct { u32, u8, u16 }) slice0[0] = {
2058            \\  (u32) .@"0" = 1
2059            \\  (u8) .@"1" = 2
2060            \\  (u16) .@"2" = 3
2061            \\}
2062            \\(struct { u32, u8, u16 }) slice0[1] = {
2063            \\  (u32) .@"0" = 4
2064            \\  (u8) .@"1" = 5
2065            \\  (u16) .@"2" = 6
2066            \\}
2067            \\(struct { u32, u8, u16 }) slice0[2] = {
2068            \\  (u32) .@"0" = 7
2069            \\  (u8) .@"1" = 8
2070            \\  (u16) .@"2" = 9
2071            \\}
2072            \\([3]u32) slice0.0 = {
2073            \\  (u32) [0] = 1
2074            \\  (u32) [1] = 4
2075            \\  (u32) [2] = 7
2076            \\}
2077            \\([3]u8) slice0.1 = {
2078            \\  (u8) [0] = 2
2079            \\  (u8) [1] = 5
2080            \\  (u8) [2] = 8
2081            \\}
2082            \\([3]u16) slice0.2 = {
2083            \\  (u16) [0] = 3
2084            \\  (u16) [1] = 6
2085            \\  (u16) [2] = 9
2086            \\}
2087            \\(lldb) frame variable --show-types -- list1 list1.len list1.capacity list1[0] list1[1] list1[2] list1.a list1.b list1.c
2088            \\(std.multi_array_list.MultiArrayList(main.Elem1)) list1 = len=3 capacity=12 {
2089            \\  (root.main.Elem1) [0] = {
2090            \\    (u32) .a = 1
2091            \\    (u8) .b = 2
2092            \\    (u16) .c = 3
2093            \\  }
2094            \\  (root.main.Elem1) [1] = {
2095            \\    (u32) .a = 4
2096            \\    (u8) .b = 5
2097            \\    (u16) .c = 6
2098            \\  }
2099            \\  (root.main.Elem1) [2] = {
2100            \\    (u32) .a = 7
2101            \\    (u8) .b = 8
2102            \\    (u16) .c = 9
2103            \\  }
2104            \\}
2105            \\(usize) list1.len = 3
2106            \\(usize) list1.capacity = 12
2107            \\(root.main.Elem1) list1[0] = {
2108            \\  (u32) .a = 1
2109            \\  (u8) .b = 2
2110            \\  (u16) .c = 3
2111            \\}
2112            \\(root.main.Elem1) list1[1] = {
2113            \\  (u32) .a = 4
2114            \\  (u8) .b = 5
2115            \\  (u16) .c = 6
2116            \\}
2117            \\(root.main.Elem1) list1[2] = {
2118            \\  (u32) .a = 7
2119            \\  (u8) .b = 8
2120            \\  (u16) .c = 9
2121            \\}
2122            \\([3]u32) list1.a = {
2123            \\  (u32) [0] = 1
2124            \\  (u32) [1] = 4
2125            \\  (u32) [2] = 7
2126            \\}
2127            \\([3]u8) list1.b = {
2128            \\  (u8) [0] = 2
2129            \\  (u8) [1] = 5
2130            \\  (u8) [2] = 8
2131            \\}
2132            \\([3]u16) list1.c = {
2133            \\  (u16) [0] = 3
2134            \\  (u16) [1] = 6
2135            \\  (u16) [2] = 9
2136            \\}
2137            \\(lldb) frame variable --show-types -- slice1 slice1.len slice1.capacity slice1[0] slice1[1] slice1[2] slice1.a slice1.b slice1.c
2138            \\(std.multi_array_list.MultiArrayList(main.Elem1).Slice) slice1 = len=3 capacity=12 {
2139            \\  (root.main.Elem1) [0] = {
2140            \\    (u32) .a = 1
2141            \\    (u8) .b = 2
2142            \\    (u16) .c = 3
2143            \\  }
2144            \\  (root.main.Elem1) [1] = {
2145            \\    (u32) .a = 4
2146            \\    (u8) .b = 5
2147            \\    (u16) .c = 6
2148            \\  }
2149            \\  (root.main.Elem1) [2] = {
2150            \\    (u32) .a = 7
2151            \\    (u8) .b = 8
2152            \\    (u16) .c = 9
2153            \\  }
2154            \\}
2155            \\(usize) slice1.len = 3
2156            \\(usize) slice1.capacity = 12
2157            \\(root.main.Elem1) slice1[0] = {
2158            \\  (u32) .a = 1
2159            \\  (u8) .b = 2
2160            \\  (u16) .c = 3
2161            \\}
2162            \\(root.main.Elem1) slice1[1] = {
2163            \\  (u32) .a = 4
2164            \\  (u8) .b = 5
2165            \\  (u16) .c = 6
2166            \\}
2167            \\(root.main.Elem1) slice1[2] = {
2168            \\  (u32) .a = 7
2169            \\  (u8) .b = 8
2170            \\  (u16) .c = 9
2171            \\}
2172            \\([3]u32) slice1.a = {
2173            \\  (u32) [0] = 1
2174            \\  (u32) [1] = 4
2175            \\  (u32) [2] = 7
2176            \\}
2177            \\([3]u8) slice1.b = {
2178            \\  (u8) [0] = 2
2179            \\  (u8) [1] = 5
2180            \\  (u8) [2] = 8
2181            \\}
2182            \\([3]u16) slice1.c = {
2183            \\  (u16) [0] = 3
2184            \\  (u16) [1] = 6
2185            \\  (u16) [2] = 9
2186            \\}
2187            \\(lldb) breakpoint delete --force 1
2188            \\1 breakpoints deleted; 0 breakpoint locations disabled.
2189        },
2190    );
2191}
2192
2193const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };
2194
2195fn addGdbTest(
2196    db: *Debugger,
2197    name: []const u8,
2198    target: *const Target,
2199    files: []const File,
2200    commands: []const u8,
2201    expected_output: []const []const u8,
2202) void {
2203    db.addTest(
2204        name,
2205        target,
2206        files,
2207        &.{
2208            db.options.gdb orelse return,
2209            "--batch",
2210            "--command",
2211        },
2212        "set remotetimeout 0",
2213        commands,
2214        &.{
2215            "--args",
2216        },
2217        expected_output,
2218    );
2219}
2220
2221fn addLldbTest(
2222    db: *Debugger,
2223    name: []const u8,
2224    target: *const Target,
2225    files: []const File,
2226    commands: []const u8,
2227    expected_output: []const []const u8,
2228) void {
2229    db.addTest(
2230        name,
2231        target,
2232        files,
2233        &.{
2234            db.options.lldb orelse return,
2235            "--batch",
2236            "--source",
2237        },
2238        "settings set plugin.process.gdb-remote.packet-timeout 0",
2239        commands,
2240        &.{
2241            "--",
2242        },
2243        expected_output,
2244    );
2245}
2246
2247/// After a failure while running a script, the debugger starts accepting commands from stdin, and
2248/// because it is empty, the debugger exits normally with status 0. Choose a non-zero status to
2249/// return from the debugger script instead to detect it running to completion and indicate success.
2250const success = 99;
2251
2252fn addTest(
2253    db: *Debugger,
2254    name: []const u8,
2255    target: *const Target,
2256    files: []const File,
2257    db_argv1: []const []const u8,
2258    db_commands: []const u8,
2259    commands: []const u8,
2260    db_argv2: []const []const u8,
2261    expected_output: []const []const u8,
2262) void {
2263    if (db.options.test_filters.len > 0) {
2264        for (db.options.test_filters) |test_filter| {
2265            if (std.mem.indexOf(u8, name, test_filter) != null) break;
2266        } else return;
2267    }
2268    if (db.options.test_target_filters.len > 0) {
2269        const triple_txt = target.resolved.query.zigTriple(db.b.allocator) catch @panic("OOM");
2270        for (db.options.test_target_filters) |filter| {
2271            if (std.mem.indexOf(u8, triple_txt, filter) != null) break;
2272        } else return;
2273    }
2274    const files_wf = db.b.addWriteFiles();
2275
2276    const mod = db.b.createModule(.{
2277        .target = target.resolved,
2278        .root_source_file = files_wf.add(files[0].path, files[0].source),
2279        .optimize = target.optimize_mode,
2280        .link_libc = target.link_libc,
2281        .single_threaded = target.single_threaded,
2282        .pic = target.pic,
2283        .strip = false,
2284    });
2285    for (files[1..]) |file| {
2286        const path = files_wf.add(file.path, file.source);
2287        if (file.import) |import| mod.addImport(import, db.b.createModule(.{
2288            .root_source_file = path,
2289        }));
2290    }
2291
2292    const exe = db.b.addExecutable(.{
2293        .name = name,
2294        .root_module = mod,
2295        .use_llvm = false,
2296        .use_lld = false,
2297    });
2298
2299    const commands_wf = db.b.addWriteFiles();
2300    const run = std.Build.Step.Run.create(db.b, db.b.fmt("run {s} {s}", .{ name, target.test_name_suffix }));
2301    run.addArgs(db_argv1);
2302    run.addFileArg(commands_wf.add(
2303        db.b.fmt("{s}.cmd", .{name}),
2304        db.b.fmt("{s}\n\n{s}\n\nquit {d}\n", .{ db_commands, commands, success }),
2305    ));
2306    run.addArgs(db_argv2);
2307    run.addArtifactArg(exe);
2308    for (expected_output) |expected| run.addCheck(.{ .expect_stdout_match = db.b.fmt("{s}\n", .{expected}) });
2309    run.addCheck(.{ .expect_term = .{ .Exited = success } });
2310    run.setStdIn(.{ .bytes = "" });
2311    db.root_step.dependOn(&run.step);
2312}
2313
2314const Debugger = @This();
2315const std = @import("std");