@zigc/lib 0.16.0-test.1 → 0.17.0-dev.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/LICENSE +19 -0
  2. package/c/math.zig +135 -35
  3. package/c/stropts.zig +17 -0
  4. package/c.zig +1 -0
  5. package/compiler/aro/aro/Attribute/names.zig +604 -589
  6. package/compiler/aro/aro/Attribute.zig +202 -116
  7. package/compiler/aro/aro/Builtins/common.zig +874 -863
  8. package/compiler/aro/aro/Builtins/eval.zig +15 -7
  9. package/compiler/aro/aro/Builtins.zig +0 -1
  10. package/compiler/aro/aro/CodeGen.zig +3 -1
  11. package/compiler/aro/aro/Compilation.zig +120 -97
  12. package/compiler/aro/aro/Diagnostics.zig +21 -17
  13. package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
  14. package/compiler/aro/aro/Driver.zig +124 -50
  15. package/compiler/aro/aro/LangOpts.zig +12 -2
  16. package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
  17. package/compiler/aro/aro/Parser.zig +336 -142
  18. package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
  19. package/compiler/aro/aro/Preprocessor.zig +127 -56
  20. package/compiler/aro/aro/Target.zig +17 -12
  21. package/compiler/aro/aro/Tokenizer.zig +31 -14
  22. package/compiler/aro/aro/Toolchain.zig +4 -7
  23. package/compiler/aro/aro/Tree.zig +178 -148
  24. package/compiler/aro/aro/TypeStore.zig +82 -24
  25. package/compiler/aro/aro/Value.zig +13 -17
  26. package/compiler/aro/aro/features.zig +1 -0
  27. package/compiler/aro/aro/pragmas/once.zig +0 -1
  28. package/compiler/aro/aro/record_layout.zig +3 -3
  29. package/compiler/aro/assembly_backend/x86_64.zig +3 -4
  30. package/compiler/aro/backend/Assembly.zig +1 -2
  31. package/compiler/aro/backend/Interner.zig +2 -2
  32. package/compiler/aro/backend/Ir.zig +100 -92
  33. package/compiler/aro/include/ptrcheck.h +49 -0
  34. package/compiler/aro/main.zig +26 -10
  35. package/compiler/build_runner.zig +1 -0
  36. package/compiler/objdump.zig +93 -0
  37. package/compiler/reduce.zig +5 -1
  38. package/compiler/resinator/compile.zig +2 -2
  39. package/compiler/resinator/main.zig +7 -1
  40. package/compiler/resinator/preprocess.zig +1 -3
  41. package/compiler/std-docs.zig +8 -1
  42. package/compiler/test_runner.zig +193 -61
  43. package/compiler/translate-c/MacroTranslator.zig +80 -11
  44. package/compiler/translate-c/PatternList.zig +1 -9
  45. package/compiler/translate-c/Scope.zig +43 -6
  46. package/compiler/translate-c/Translator.zig +364 -126
  47. package/compiler/translate-c/ast.zig +19 -11
  48. package/compiler/translate-c/main.zig +75 -16
  49. package/compiler_rt/cos.zig +141 -52
  50. package/compiler_rt/limb64.zig +266 -0
  51. package/compiler_rt/long_double.zig +37 -0
  52. package/compiler_rt/mulo.zig +6 -1
  53. package/compiler_rt/rem_pio2l.zig +173 -0
  54. package/compiler_rt/sin.zig +140 -55
  55. package/compiler_rt/sincos.zig +279 -72
  56. package/compiler_rt/tan.zig +118 -47
  57. package/compiler_rt/trig.zig +256 -6
  58. package/compiler_rt.zig +2 -0
  59. package/fuzzer.zig +855 -307
  60. package/libc/musl/src/math/pow.c +343 -0
  61. package/package.json +1 -1
  62. package/std/Build/Fuzz.zig +6 -19
  63. package/std/Build/Module.zig +1 -1
  64. package/std/Build/Step/CheckObject.zig +3 -3
  65. package/std/Build/Step/Compile.zig +18 -0
  66. package/std/Build/Step/ConfigHeader.zig +49 -33
  67. package/std/Build/Step/InstallArtifact.zig +18 -0
  68. package/std/Build/Step/Run.zig +536 -87
  69. package/std/Build/Step/TranslateC.zig +0 -6
  70. package/std/Build/Step.zig +8 -15
  71. package/std/Build/WebServer.zig +29 -17
  72. package/std/Build/abi.zig +47 -11
  73. package/std/Build.zig +17 -14
  74. package/std/Io/Dispatch.zig +2 -0
  75. package/std/Io/File/Reader.zig +3 -1
  76. package/std/Io/File.zig +1 -0
  77. package/std/Io/Kqueue.zig +2 -2
  78. package/std/Io/Threaded.zig +181 -143
  79. package/std/Io/Uring.zig +2 -1
  80. package/std/Io.zig +970 -2
  81. package/std/Target.zig +3 -2
  82. package/std/Thread.zig +8 -3
  83. package/std/array_hash_map.zig +96 -555
  84. package/std/array_list.zig +22 -31
  85. package/std/bit_set.zig +22 -6
  86. package/std/builtin/assembly.zig +68 -0
  87. package/std/c.zig +17 -17
  88. package/std/compress/flate/Compress.zig +3 -3
  89. package/std/crypto/Certificate/Bundle.zig +15 -1
  90. package/std/crypto/codecs/asn1.zig +33 -18
  91. package/std/crypto/codecs/base64_hex_ct.zig +14 -4
  92. package/std/debug/Dwarf.zig +29 -9
  93. package/std/debug/Info.zig +4 -0
  94. package/std/debug/MachOFile.zig +46 -8
  95. package/std/debug/Pdb.zig +539 -36
  96. package/std/debug/SelfInfo/Elf.zig +19 -18
  97. package/std/debug/SelfInfo/MachO.zig +18 -7
  98. package/std/debug/SelfInfo/Windows.zig +138 -36
  99. package/std/debug.zig +179 -65
  100. package/std/enums.zig +25 -19
  101. package/std/heap/ArenaAllocator.zig +145 -154
  102. package/std/heap/debug_allocator.zig +7 -7
  103. package/std/http/Client.zig +10 -6
  104. package/std/http.zig +11 -9
  105. package/std/json/Stringify.zig +3 -3
  106. package/std/json/dynamic.zig +4 -4
  107. package/std/math/big/int.zig +16 -17
  108. package/std/mem/Allocator.zig +4 -5
  109. package/std/mem.zig +48 -0
  110. package/std/os/emscripten.zig +2 -18
  111. package/std/os/linux/arc.zig +144 -0
  112. package/std/os/linux.zig +21 -4
  113. package/std/os/windows.zig +2 -2
  114. package/std/pdb.zig +143 -4
  115. package/std/posix.zig +6 -12
  116. package/std/priority_dequeue.zig +13 -12
  117. package/std/priority_queue.zig +5 -4
  118. package/std/process/Child.zig +1 -1
  119. package/std/process/Environ.zig +1 -1
  120. package/std/start.zig +17 -4
  121. package/std/std.zig +19 -6
  122. package/std/testing/FailingAllocator.zig +4 -4
  123. package/std/testing/Smith.zig +37 -2
  124. package/std/zig/Ast/Render.zig +186 -458
  125. package/std/zig/Ast.zig +0 -4
  126. package/std/zig/AstGen.zig +44 -7
  127. package/std/zig/AstSmith.zig +2602 -0
  128. package/std/zig/Client.zig +8 -3
  129. package/std/zig/Parse.zig +83 -74
  130. package/std/zig/Server.zig +26 -0
  131. package/std/zig/Zir.zig +17 -0
  132. package/std/zig/c_translation/helpers.zig +14 -9
  133. package/std/zig/llvm/Builder.zig +107 -48
  134. package/std/zig/system.zig +20 -4
  135. package/std/zig/tokenizer.zig +2 -1
  136. package/std/zig.zig +6 -0
  137. package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
  138. package/libc/mingw/complex/cabs.c +0 -48
  139. package/libc/mingw/complex/cabsf.c +0 -48
  140. package/libc/mingw/complex/cacos.c +0 -50
  141. package/libc/mingw/complex/cacosf.c +0 -50
  142. package/libc/mingw/complex/carg.c +0 -48
  143. package/libc/mingw/complex/cargf.c +0 -48
  144. package/libc/mingw/complex/casin.c +0 -50
  145. package/libc/mingw/complex/casinf.c +0 -50
  146. package/libc/mingw/complex/catan.c +0 -50
  147. package/libc/mingw/complex/catanf.c +0 -50
  148. package/libc/mingw/complex/ccos.c +0 -50
  149. package/libc/mingw/complex/ccosf.c +0 -50
  150. package/libc/mingw/complex/cexp.c +0 -48
  151. package/libc/mingw/complex/cexpf.c +0 -48
  152. package/libc/mingw/complex/cimag.c +0 -48
  153. package/libc/mingw/complex/cimagf.c +0 -48
  154. package/libc/mingw/complex/clog.c +0 -48
  155. package/libc/mingw/complex/clog10.c +0 -49
  156. package/libc/mingw/complex/clog10f.c +0 -49
  157. package/libc/mingw/complex/clogf.c +0 -48
  158. package/libc/mingw/complex/conj.c +0 -48
  159. package/libc/mingw/complex/conjf.c +0 -48
  160. package/libc/mingw/complex/cpow.c +0 -48
  161. package/libc/mingw/complex/cpowf.c +0 -48
  162. package/libc/mingw/complex/cproj.c +0 -48
  163. package/libc/mingw/complex/cprojf.c +0 -48
  164. package/libc/mingw/complex/creal.c +0 -48
  165. package/libc/mingw/complex/crealf.c +0 -48
  166. package/libc/mingw/complex/csin.c +0 -50
  167. package/libc/mingw/complex/csinf.c +0 -50
  168. package/libc/mingw/complex/csqrt.c +0 -48
  169. package/libc/mingw/complex/csqrtf.c +0 -48
  170. package/libc/mingw/complex/ctan.c +0 -50
  171. package/libc/mingw/complex/ctanf.c +0 -50
  172. package/libc/mingw/math/arm/s_rint.c +0 -86
  173. package/libc/mingw/math/arm/s_rintf.c +0 -51
  174. package/libc/mingw/math/arm/sincos.S +0 -30
  175. package/libc/mingw/math/arm-common/sincosl.c +0 -13
  176. package/libc/mingw/math/arm64/rint.c +0 -12
  177. package/libc/mingw/math/arm64/rintf.c +0 -12
  178. package/libc/mingw/math/arm64/sincos.S +0 -32
  179. package/libc/mingw/math/bsd_private_base.h +0 -148
  180. package/libc/mingw/math/frexpf.c +0 -13
  181. package/libc/mingw/math/frexpl.c +0 -71
  182. package/libc/mingw/math/x86/acosf.c +0 -29
  183. package/libc/mingw/math/x86/atanf.c +0 -23
  184. package/libc/mingw/math/x86/atanl.c +0 -18
  185. package/libc/mingw/math/x86/cos.def.h +0 -65
  186. package/libc/mingw/math/x86/cosl.c +0 -46
  187. package/libc/mingw/math/x86/cosl_internal.S +0 -55
  188. package/libc/mingw/math/x86/ldexp.c +0 -23
  189. package/libc/mingw/math/x86/scalbn.S +0 -41
  190. package/libc/mingw/math/x86/scalbnf.S +0 -40
  191. package/libc/mingw/math/x86/sin.def.h +0 -65
  192. package/libc/mingw/math/x86/sinl.c +0 -46
  193. package/libc/mingw/math/x86/sinl_internal.S +0 -58
  194. package/libc/mingw/math/x86/tanl.S +0 -62
  195. package/libc/mingw/misc/btowc.c +0 -28
  196. package/libc/mingw/misc/wcstof.c +0 -66
  197. package/libc/mingw/misc/wcstoimax.c +0 -132
  198. package/libc/mingw/misc/wcstoumax.c +0 -126
  199. package/libc/mingw/misc/wctob.c +0 -29
  200. package/libc/mingw/misc/winbs_uint64.c +0 -6
  201. package/libc/mingw/misc/winbs_ulong.c +0 -6
  202. package/libc/mingw/misc/winbs_ushort.c +0 -6
  203. package/libc/mingw/stdio/_Exit.c +0 -10
  204. package/libc/mingw/stdio/_findfirst64i32.c +0 -21
  205. package/libc/mingw/stdio/_findnext64i32.c +0 -21
  206. package/libc/mingw/stdio/_fstat64i32.c +0 -37
  207. package/libc/mingw/stdio/_stat64i32.c +0 -37
  208. package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
  209. package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
  210. package/libc/mingw/stdio/_wstat64i32.c +0 -37
  211. package/libc/musl/src/legacy/isastream.c +0 -7
  212. package/libc/musl/src/legacy/valloc.c +0 -8
  213. package/libc/musl/src/math/__cosl.c +0 -96
  214. package/libc/musl/src/math/__sinl.c +0 -78
  215. package/libc/musl/src/math/__tanl.c +0 -143
  216. package/libc/musl/src/math/aarch64/lrint.c +0 -10
  217. package/libc/musl/src/math/aarch64/lrintf.c +0 -10
  218. package/libc/musl/src/math/aarch64/rintf.c +0 -7
  219. package/libc/musl/src/math/cosl.c +0 -39
  220. package/libc/musl/src/math/fdim.c +0 -10
  221. package/libc/musl/src/math/finite.c +0 -7
  222. package/libc/musl/src/math/finitef.c +0 -7
  223. package/libc/musl/src/math/frexp.c +0 -23
  224. package/libc/musl/src/math/frexpf.c +0 -23
  225. package/libc/musl/src/math/frexpl.c +0 -29
  226. package/libc/musl/src/math/i386/lrint.c +0 -8
  227. package/libc/musl/src/math/i386/lrintf.c +0 -8
  228. package/libc/musl/src/math/i386/rintf.c +0 -7
  229. package/libc/musl/src/math/lrint.c +0 -72
  230. package/libc/musl/src/math/lrintf.c +0 -8
  231. package/libc/musl/src/math/powerpc64/lrint.c +0 -16
  232. package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
  233. package/libc/musl/src/math/rintf.c +0 -30
  234. package/libc/musl/src/math/s390x/rintf.c +0 -15
  235. package/libc/musl/src/math/sincosl.c +0 -60
  236. package/libc/musl/src/math/sinl.c +0 -41
  237. package/libc/musl/src/math/tanl.c +0 -29
  238. package/libc/musl/src/math/x32/lrint.s +0 -5
  239. package/libc/musl/src/math/x32/lrintf.s +0 -5
  240. package/libc/musl/src/math/x86_64/lrint.c +0 -8
  241. package/libc/musl/src/math/x86_64/lrintf.c +0 -8
  242. package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
@@ -1,16 +1,19 @@
1
1
  const std = @import("std");
2
+ const assert = std.debug.assert;
3
+
2
4
  const backend = @import("../../backend.zig");
3
5
  const Interner = backend.Interner;
6
+
4
7
  const Builtins = @import("../Builtins.zig");
5
8
  const Parser = @import("../Parser.zig");
6
9
  const Tree = @import("../Tree.zig");
7
10
  const TypeStore = @import("../TypeStore.zig");
8
- const Type = TypeStore.Type;
9
11
  const QualType = TypeStore.QualType;
12
+ const Type = TypeStore.Type;
10
13
  const Value = @import("../Value.zig");
11
14
 
12
15
  fn makeNan(comptime T: type, str: []const u8) T {
13
- const UnsignedSameSize = std.meta.Int(.unsigned, @bitSizeOf(T));
16
+ const UnsignedSameSize = @Int(.unsigned, @bitSizeOf(T));
14
17
  const parsed = std.fmt.parseUnsigned(UnsignedSameSize, str[0 .. str.len - 1], 0) catch 0;
15
18
  const bits: switch (T) {
16
19
  f32 => u23,
@@ -24,7 +27,6 @@ fn makeNan(comptime T: type, str: []const u8) T {
24
27
 
25
28
  pub fn eval(expanded: Builtins.Expanded, p: *Parser, args: []const Tree.Node.Index) !Value {
26
29
  if (!expanded.attributes.const_evaluable) return .{};
27
-
28
30
  switch (expanded.tag) {
29
31
  .common => |tag| switch (tag) {
30
32
  .__builtin_inff,
@@ -47,12 +49,12 @@ pub fn eval(expanded: Builtins.Expanded, p: *Parser, args: []const Tree.Node.Ind
47
49
  return Value.intern(p.comp, .{ .float = f });
48
50
  },
49
51
  .__builtin_isinf => blk: {
50
- if (args.len == 0) break :blk;
52
+ assert(args.len == 1);
51
53
  const val = p.tree.value_map.get(args[0]) orelse break :blk;
52
54
  return Value.fromBool(val.isInf(p.comp));
53
55
  },
54
56
  .__builtin_isinf_sign => blk: {
55
- if (args.len == 0) break :blk;
57
+ assert(args.len == 1);
56
58
  const val = p.tree.value_map.get(args[0]) orelse break :blk;
57
59
  switch (val.isInfSign(p.comp)) {
58
60
  .unknown => {},
@@ -62,12 +64,12 @@ pub fn eval(expanded: Builtins.Expanded, p: *Parser, args: []const Tree.Node.Ind
62
64
  }
63
65
  },
64
66
  .__builtin_isnan => blk: {
65
- if (args.len == 0) break :blk;
67
+ assert(args.len == 1);
66
68
  const val = p.tree.value_map.get(args[0]) orelse break :blk;
67
69
  return Value.fromBool(val.isNan(p.comp));
68
70
  },
69
71
  .__builtin_nan => blk: {
70
- if (args.len == 0) break :blk;
72
+ assert(args.len == 1);
71
73
  const val = p.getDecayedStringLiteral(args[0]) orelse break :blk;
72
74
  const bytes = p.comp.interner.get(val.ref()).bytes;
73
75
 
@@ -80,6 +82,12 @@ pub fn eval(expanded: Builtins.Expanded, p: *Parser, args: []const Tree.Node.Ind
80
82
  };
81
83
  return Value.intern(p.comp, .{ .float = f });
82
84
  },
85
+ .__builtin_constant_p => {
86
+ assert(args.len == 1);
87
+ const arg = args[0];
88
+ const val = p.tree.value_map.get(arg) orelse return Value.fromBool(p.isAddressOfStringLiteral(arg));
89
+ return Value.fromBool(!val.isPointer(p.comp));
90
+ },
83
91
  else => {},
84
92
  },
85
93
  else => {},
@@ -264,7 +264,6 @@ fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *C
264
264
  _ = address_space; // TODO: handle address space
265
265
  const pointer_qt = try comp.type_store.put(comp.gpa, .{ .pointer = .{
266
266
  .child = builder.finish() catch unreachable,
267
- .decayed = null,
268
267
  } });
269
268
 
270
269
  builder.@"const" = null;
@@ -2,7 +2,7 @@ const std = @import("std");
2
2
  const Allocator = std.mem.Allocator;
3
3
  const assert = std.debug.assert;
4
4
 
5
- const backend = @import("backend");
5
+ const backend = @import("../backend.zig");
6
6
  const Interner = backend.Interner;
7
7
  const Ir = backend.Ir;
8
8
  const Builder = Ir.Builder;
@@ -867,6 +867,8 @@ fn genExpr(c: *CodeGen, node_index: Node.Index) Error!Ir.Ref {
867
867
  .imag_expr,
868
868
  .real_expr,
869
869
  .sizeof_expr,
870
+ .builtin_va_arg_pack,
871
+ .builtin_va_arg_pack_len,
870
872
  => return c.fail("TODO CodeGen.genExpr {s}\n", .{@tagName(node)}),
871
873
  else => unreachable, // Not an expression.
872
874
  }
@@ -71,34 +71,23 @@ pub const Environment = struct {
71
71
  /// used for __DATE__, __TIME__, and __TIMESTAMP__
72
72
  provided: u64,
73
73
 
74
- pub const default: @This() = .{ .provided = 0 };
74
+ pub const default: SourceEpoch = .{ .provided = 0 };
75
75
  };
76
76
 
77
- pub fn loadAll(allocator: std.mem.Allocator, environ_map: *const std.process.Environ.Map) !Environment {
77
+ /// Load all of the environment variables from an environ map. Does not copy values.
78
+ pub fn loadAll(environ_map: *const std.process.Environ.Map) Environment {
78
79
  var env: Environment = .{};
79
- errdefer env.deinit(allocator);
80
80
 
81
81
  inline for (@typeInfo(@TypeOf(env)).@"struct".fields) |field| {
82
82
  std.debug.assert(@field(env, field.name) == null);
83
83
 
84
84
  var env_var_buf: [field.name.len]u8 = undefined;
85
85
  const env_var_name = std.ascii.upperString(&env_var_buf, field.name);
86
- const val: ?[]const u8 = if (environ_map.get(env_var_name)) |v| try allocator.dupe(u8, v) else null;
87
- @field(env, field.name) = val;
86
+ @field(env, field.name) = environ_map.get(env_var_name);
88
87
  }
89
88
  return env;
90
89
  }
91
90
 
92
- /// Use this only if environment slices were allocated with `allocator` (such as via `loadAll`)
93
- pub fn deinit(self: *Environment, allocator: std.mem.Allocator) void {
94
- inline for (@typeInfo(@TypeOf(self.*)).@"struct".fields) |field| {
95
- if (@field(self, field.name)) |slice| {
96
- allocator.free(slice);
97
- }
98
- }
99
- self.* = undefined;
100
- }
101
-
102
91
  pub fn sourceEpoch(self: *const Environment, io: Io) !SourceEpoch {
103
92
  const max_timestamp = 253402300799; // Dec 31 9999 23:59:59
104
93
 
@@ -148,7 +137,7 @@ gpa: Allocator,
148
137
  /// Allocations in this arena live all the way until `Compilation.deinit`.
149
138
  arena: Allocator,
150
139
  io: Io,
151
- cwd: Io.Dir,
140
+ cwd: std.Io.Dir,
152
141
  diagnostics: *Diagnostics,
153
142
 
154
143
  sources: std.StringArrayHashMapUnmanaged(Source) = .empty,
@@ -175,37 +164,48 @@ pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .empty,
175
164
  /// Used by MS extensions which allow searching for includes relative to the directory of the main source file.
176
165
  ms_cwd_source_id: ?Source.Id = null,
177
166
 
178
- pub fn init(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, cwd: Io.Dir) Compilation {
179
- return .{
180
- .gpa = gpa,
181
- .arena = arena,
182
- .io = io,
183
- .diagnostics = diagnostics,
184
- .cwd = cwd,
185
- };
186
- }
187
-
188
- /// Initialize Compilation with default environment,
189
- /// pragma handlers and emulation mode set to target.
190
- pub fn initDefault(
167
+ pub const InitOptions = struct {
191
168
  gpa: Allocator,
192
169
  arena: Allocator,
193
170
  io: Io,
194
171
  diagnostics: *Diagnostics,
195
- cwd: Io.Dir,
196
- environ_map: *const std.process.Environ.Map,
197
- ) !Compilation {
172
+
173
+ /// Used to initiate `Compilation.Environment`, values are not copied.
174
+ environ_map: ?*const std.process.Environ.Map,
175
+ /// Defaults to `std.Io.Dir.cwd()`
176
+ cwd: ?std.Io.Dir = null,
177
+
178
+ add_default_pragma_handlers: bool = true,
179
+
180
+ pub const testing: InitOptions = .{
181
+ .gpa = std.testing.allocator,
182
+ .arena = undefined,
183
+ .io = std.testing.io,
184
+ .diagnostics = undefined,
185
+ .environ_map = null,
186
+ .add_default_pragma_handlers = false,
187
+ };
188
+ };
189
+
190
+ /// Initialize Compilation with default environment,
191
+ /// pragma handlers and emulation mode set to target.
192
+ pub fn init(options: InitOptions) !Compilation {
198
193
  var comp: Compilation = .{
199
- .gpa = gpa,
200
- .arena = arena,
201
- .io = io,
202
- .diagnostics = diagnostics,
203
- .environment = try Environment.loadAll(gpa, environ_map),
204
- .cwd = cwd,
194
+ .gpa = options.gpa,
195
+ .arena = options.arena,
196
+ .io = options.io,
197
+ .diagnostics = options.diagnostics,
198
+ .cwd = options.cwd orelse .cwd(),
205
199
  };
206
200
  errdefer comp.deinit();
207
- try comp.addDefaultPragmaHandlers();
208
- comp.langopts.setEmulatedCompiler(comp.target.systemCompiler());
201
+
202
+ if (options.environ_map) |map| {
203
+ comp.environment = .loadAll(map);
204
+ }
205
+
206
+ if (options.add_default_pragma_handlers) {
207
+ try comp.addDefaultPragmaHandlers();
208
+ }
209
209
  return comp;
210
210
  }
211
211
 
@@ -228,7 +228,6 @@ pub fn deinit(comp: *Compilation) void {
228
228
  comp.builtins.deinit(gpa);
229
229
  comp.string_interner.deinit(gpa);
230
230
  comp.interner.deinit(gpa);
231
- comp.environment.deinit(gpa);
232
231
  comp.type_store.deinit(gpa);
233
232
  comp.* = undefined;
234
233
  }
@@ -275,17 +274,18 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
275
274
  }
276
275
 
277
276
  try w.writeAll(
277
+ \\#define __ARO_EMULATE_NO__ 0
278
278
  \\#define __ARO_EMULATE_CLANG__ 1
279
279
  \\#define __ARO_EMULATE_GCC__ 2
280
280
  \\#define __ARO_EMULATE_MSVC__ 3
281
281
  \\
282
282
  );
283
- const emulated = switch (comp.langopts.emulate) {
283
+ try w.print("#define __ARO_EMULATE__ {s}\n", .{switch (comp.langopts.emulate) {
284
+ .no => "__ARO_EMULATE_NO__",
284
285
  .clang => "__ARO_EMULATE_CLANG__",
285
286
  .gcc => "__ARO_EMULATE_GCC__",
286
287
  .msvc => "__ARO_EMULATE_MSVC__",
287
- };
288
- try w.print("#define __ARO_EMULATE__ {s}\n", .{emulated});
288
+ }});
289
289
 
290
290
  if (comp.langopts.emulate == .msvc) {
291
291
  try w.writeAll("#define _MSC_VER 1933\n");
@@ -375,6 +375,7 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
375
375
  .watchos,
376
376
  => {
377
377
  try define(w, "__APPLE__");
378
+ try w.writeAll("#define __APPLE_CC__ 6000\n");
378
379
 
379
380
  const version = target.os.version_range.semver.min;
380
381
  var version_buf: [8]u8 = undefined;
@@ -647,6 +648,7 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
647
648
  try define(w, "__ppc__");
648
649
  try define(w, "__PPC__");
649
650
  try define(w, "_ARCH_PPC");
651
+ try w.print("#define _CALL_ELF {d}\n", .{target.ppcElfVersion()});
650
652
  },
651
653
  .powerpc64,
652
654
  .powerpc64le,
@@ -661,7 +663,7 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
661
663
  try define(w, "__PPC64__");
662
664
  try define(w, "_ARCH_PPC");
663
665
  try define(w, "_ARCH_PPC64");
664
- try w.writeAll("#define _CALL_ELF 2\n");
666
+ try w.print("#define _CALL_ELF {d}\n", .{target.ppcElfVersion()});
665
667
  },
666
668
  .sparc64 => {
667
669
  try defineStd(w, "sparc", is_gnu);
@@ -686,8 +688,19 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
686
688
  try define(w, "__thumb__");
687
689
  }
688
690
  },
689
- .aarch64, .aarch64_be => {
691
+ .aarch64, .aarch64_be => |arch| {
690
692
  try define(w, "__aarch64__");
693
+ switch (arch) {
694
+ .aarch64 => {
695
+ try define(w, "__AARCH64EL__");
696
+ },
697
+ .aarch64_be => {
698
+ try define(w, "__AARCH64EB__");
699
+ try define(w, "__AARCH_BIG_ENDIAN");
700
+ try define(w, "__ARM_BIG_ENDIAN");
701
+ },
702
+ else => unreachable,
703
+ }
691
704
  if (target.os.tag.isDarwin()) {
692
705
  try define(w, "__AARCH64_SIMD__");
693
706
  if (ptr_width == 32) {
@@ -839,6 +852,7 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
839
852
  }
840
853
  },
841
854
  .riscv32, .riscv32be, .riscv64, .riscv64be => {
855
+ try define(w, "__riscv");
842
856
  try w.print("#define __riscv_xlen {d}\n", .{ptr_width});
843
857
  },
844
858
  else => {},
@@ -910,6 +924,7 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
910
924
  \\#define __ATOMIC_CHAR16_T_LOCK_FREE 1
911
925
  \\#define __ATOMIC_CHAR32_T_LOCK_FREE 1
912
926
  \\#define __ATOMIC_WCHAR_T_LOCK_FREE 1
927
+ \\#define __ATOMIC_WINT_T_LOCK_FREE 1
913
928
  \\#define __ATOMIC_SHORT_LOCK_FREE 1
914
929
  \\#define __ATOMIC_INT_LOCK_FREE 1
915
930
  \\#define __ATOMIC_LONG_LOCK_FREE 1
@@ -922,7 +937,15 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
922
937
  }
923
938
 
924
939
  // types
925
- if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
940
+ if (comp.getCharSignedness() == .unsigned) {
941
+ try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
942
+ }
943
+ if (comp.type_store.wchar.signedness(comp) == .unsigned) {
944
+ try w.writeAll("#define __WCHAR_UNSIGNED__ 1\n");
945
+ }
946
+ if (comp.type_store.wint.signedness(comp) == .unsigned) {
947
+ try w.writeAll("#define __WINT_UNSIGNED__ 1\n");
948
+ }
926
949
  try w.writeAll("#define __CHAR_BIT__ 8\n");
927
950
 
928
951
  // int maxs
@@ -933,7 +956,7 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
933
956
  try comp.generateIntMaxAndWidth(w, "LONG", .long);
934
957
  try comp.generateIntMaxAndWidth(w, "LONG_LONG", .long_long);
935
958
  try comp.generateIntMaxAndWidth(w, "WCHAR", comp.type_store.wchar);
936
- // try comp.generateIntMax(w, "WINT", comp.type_store.wchar);
959
+ try comp.generateIntMaxAndWidth(w, "WINT", comp.type_store.wint);
937
960
  try comp.generateIntMaxAndWidth(w, "INTMAX", comp.type_store.intmax);
938
961
  try comp.generateIntMaxAndWidth(w, "SIZE", comp.type_store.size);
939
962
  try comp.generateIntMaxAndWidth(w, "UINTMAX", try comp.type_store.intmax.makeIntUnsigned(comp));
@@ -957,7 +980,7 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
957
980
  try comp.generateSizeofType(w, "__SIZEOF_PTRDIFF_T__", comp.type_store.ptrdiff);
958
981
  try comp.generateSizeofType(w, "__SIZEOF_SIZE_T__", comp.type_store.size);
959
982
  try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.type_store.wchar);
960
- // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .void_pointer);
983
+ try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", comp.type_store.wint);
961
984
 
962
985
  if (target.hasInt128()) {
963
986
  try comp.generateSizeofType(w, "__SIZEOF_INT128__", .int128);
@@ -968,14 +991,15 @@ fn generateSystemDefines(comp: *Compilation, w: *Io.Writer) !void {
968
991
  try comp.generateTypeMacro(w, "__UINTPTR_TYPE__", try comp.type_store.intptr.makeIntUnsigned(comp));
969
992
 
970
993
  try comp.generateTypeMacro(w, "__INTMAX_TYPE__", comp.type_store.intmax);
971
- try comp.generateSuffixMacro("__INTMAX", w, comp.type_store.intptr);
994
+ try comp.generateIntLiteralMacros("__INTMAX", w, comp.type_store.intptr);
972
995
 
973
996
  try comp.generateTypeMacro(w, "__UINTMAX_TYPE__", try comp.type_store.intmax.makeIntUnsigned(comp));
974
- try comp.generateSuffixMacro("__UINTMAX", w, try comp.type_store.intptr.makeIntUnsigned(comp));
997
+ try comp.generateIntLiteralMacros("__UINTMAX", w, try comp.type_store.intptr.makeIntUnsigned(comp));
975
998
 
976
999
  try comp.generateTypeMacro(w, "__PTRDIFF_TYPE__", comp.type_store.ptrdiff);
977
1000
  try comp.generateTypeMacro(w, "__SIZE_TYPE__", comp.type_store.size);
978
1001
  try comp.generateTypeMacro(w, "__WCHAR_TYPE__", comp.type_store.wchar);
1002
+ try comp.generateTypeMacro(w, "__WINT_TYPE__", comp.type_store.wint);
979
1003
  try comp.generateTypeMacro(w, "__CHAR16_TYPE__", comp.type_store.uint_least16_t);
980
1004
  try comp.generateTypeMacro(w, "__CHAR32_TYPE__", comp.type_store.uint_least32_t);
981
1005
 
@@ -1167,8 +1191,10 @@ fn generateTypeMacro(comp: *const Compilation, w: *Io.Writer, name: []const u8,
1167
1191
  }
1168
1192
 
1169
1193
  pub fn float80Type(comp: *const Compilation) ?QualType {
1170
- if (comp.langopts.emulate != .gcc) return null;
1171
- return comp.target.float80Type();
1194
+ return switch (comp.langopts.emulate) {
1195
+ .no, .gcc => comp.target.float80Type(),
1196
+ .msvc, .clang => null,
1197
+ };
1172
1198
  }
1173
1199
 
1174
1200
  /// Smallest integer type with at least N bits
@@ -1292,8 +1318,14 @@ fn generateFmt(comp: *const Compilation, prefix: []const u8, w: *Io.Writer, qt:
1292
1318
  }
1293
1319
  }
1294
1320
 
1295
- fn generateSuffixMacro(comp: *const Compilation, prefix: []const u8, w: *Io.Writer, qt: QualType) !void {
1296
- return w.print("#define {s}_C_SUFFIX__ {s}\n", .{ prefix, qt.intValueSuffix(comp) });
1321
+ fn generateIntLiteralMacros(comp: *const Compilation, prefix: []const u8, w: *Io.Writer, qt: QualType) !void {
1322
+ const suffix = qt.intValueSuffix(comp);
1323
+ try w.print("#define {s}_C_SUFFIX__ {s}\n", .{ prefix, suffix });
1324
+ if (suffix.len == 0) {
1325
+ try w.print("#define {s}_C(c) c\n", .{prefix});
1326
+ } else {
1327
+ try w.print("#define {s}_C(c) c##{s}\n", .{ prefix, suffix });
1328
+ }
1297
1329
  }
1298
1330
 
1299
1331
  /// Generate the following for a type:
@@ -1322,7 +1354,7 @@ fn generateExactWidthType(comp: *Compilation, w: *Io.Writer, original_qt: QualTy
1322
1354
  const prefix = full[0 .. full.len - suffix.len]; // remove "_TYPE__"
1323
1355
 
1324
1356
  try comp.generateFmt(prefix, w, qt);
1325
- try comp.generateSuffixMacro(prefix, w, qt);
1357
+ try comp.generateIntLiteralMacros(prefix, w, qt);
1326
1358
  }
1327
1359
 
1328
1360
  pub fn hasFloat128(comp: *const Compilation) bool {
@@ -1414,7 +1446,7 @@ pub fn maxArrayBytes(comp: *const Compilation) u64 {
1414
1446
  pub fn fixedEnumTagType(comp: *const Compilation) ?QualType {
1415
1447
  switch (comp.langopts.emulate) {
1416
1448
  .msvc => return .int,
1417
- .clang => if (comp.target.os.tag == .windows and comp.target.abi == .msvc) return .int,
1449
+ .no, .clang => if (comp.target.os.tag == .windows and comp.target.abi == .msvc) return .int,
1418
1450
  .gcc => {},
1419
1451
  }
1420
1452
  return null;
@@ -1424,6 +1456,10 @@ pub fn getCharSignedness(comp: *const Compilation) std.builtin.Signedness {
1424
1456
  return comp.langopts.char_signedness_override orelse comp.target.cCharSignedness();
1425
1457
  }
1426
1458
 
1459
+ pub fn hasClangStyleBoundsSafety(comp: *const Compilation) bool {
1460
+ return comp.langopts.bounds_safety == .clang;
1461
+ }
1462
+
1427
1463
  pub fn getSource(comp: *const Compilation, id: Source.Id) Source {
1428
1464
  if (id.alias) {
1429
1465
  return comp.source_aliases.items[@intFromEnum(id.index)];
@@ -1643,14 +1679,12 @@ fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kin
1643
1679
  return error.FileNotFound;
1644
1680
  }
1645
1681
 
1646
- const io = comp.io;
1647
-
1648
- const file = try comp.cwd.openFile(io, path, .{});
1649
- defer file.close(io);
1682
+ const file = try comp.cwd.openFile(comp.io, path, .{});
1683
+ defer file.close(comp.io);
1650
1684
  return comp.addSourceFromFile(file, path, kind);
1651
1685
  }
1652
1686
 
1653
- pub fn addSourceFromFile(comp: *Compilation, file: Io.File, path: []const u8, kind: Source.Kind) !Source {
1687
+ pub fn addSourceFromFile(comp: *Compilation, file: std.Io.File, path: []const u8, kind: Source.Kind) !Source {
1654
1688
  const contents = try comp.getFileContents(file, .unlimited);
1655
1689
  errdefer comp.gpa.free(contents);
1656
1690
  return comp.addSourceFromOwnedBuffer(path, contents, kind);
@@ -1718,8 +1752,7 @@ pub fn initSearchPath(comp: *Compilation, includes: []const Include, verbose: bo
1718
1752
  }
1719
1753
  }
1720
1754
  fn addToSearchPath(comp: *Compilation, include: Include, verbose: bool) !void {
1721
- const io = comp.io;
1722
- comp.cwd.access(io, include.path, .{}) catch {
1755
+ comp.cwd.access(comp.io, include.path, .{}) catch {
1723
1756
  if (verbose) {
1724
1757
  std.debug.print("ignoring nonexistent directory \"{s}\"\n", .{include.path});
1725
1758
  return;
@@ -1979,14 +2012,12 @@ fn getPathContents(comp: *Compilation, path: []const u8, limit: Io.Limit) ![]u8
1979
2012
  return error.FileNotFound;
1980
2013
  }
1981
2014
 
1982
- const io = comp.io;
1983
-
1984
- const file = try comp.cwd.openFile(io, path, .{});
1985
- defer file.close(io);
2015
+ const file = try comp.cwd.openFile(comp.io, path, .{});
2016
+ defer file.close(comp.io);
1986
2017
  return comp.getFileContents(file, limit);
1987
2018
  }
1988
2019
 
1989
- fn getFileContents(comp: *Compilation, file: Io.File, limit: Io.Limit) ![]u8 {
2020
+ fn getFileContents(comp: *Compilation, file: std.Io.File, limit: Io.Limit) ![]u8 {
1990
2021
  var file_buf: [4096]u8 = undefined;
1991
2022
  var file_reader = file.reader(comp.io, &file_buf);
1992
2023
 
@@ -2168,9 +2199,8 @@ pub fn locSlice(comp: *const Compilation, loc: Source.Location) []const u8 {
2168
2199
  }
2169
2200
 
2170
2201
  pub fn getSourceMTimeUncached(comp: *const Compilation, source_id: Source.Id) ?u64 {
2171
- const io = comp.io;
2172
2202
  const source = comp.getSource(source_id);
2173
- if (comp.cwd.statFile(io, source.path, .{})) |stat| {
2203
+ if (comp.cwd.statFile(comp.io, source.path, .{})) |stat| {
2174
2204
  return std.math.cast(u64, stat.mtime.toSeconds());
2175
2205
  } else |_| {
2176
2206
  return null;
@@ -2257,10 +2287,9 @@ pub const Diagnostic = struct {
2257
2287
  test "addSourceFromBuffer" {
2258
2288
  const Test = struct {
2259
2289
  fn addSourceFromBuffer(str: []const u8, expected: []const u8, warning_count: u32, splices: []const u32) !void {
2260
- var arena: std.heap.ArenaAllocator = .init(std.testing.allocator);
2261
- defer arena.deinit();
2262
2290
  var diagnostics: Diagnostics = .{ .output = .ignore };
2263
- var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd());
2291
+ var comp = try Compilation.init(.testing);
2292
+ comp.diagnostics = &diagnostics;
2264
2293
  defer comp.deinit();
2265
2294
 
2266
2295
  const source = try comp.addSourceFromBuffer("path", str);
@@ -2271,10 +2300,8 @@ test "addSourceFromBuffer" {
2271
2300
  }
2272
2301
 
2273
2302
  fn withAllocationFailures(allocator: std.mem.Allocator) !void {
2274
- var arena: std.heap.ArenaAllocator = .init(allocator);
2275
- defer arena.deinit();
2276
- var diagnostics: Diagnostics = .{ .output = .ignore };
2277
- var comp = Compilation.init(allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd());
2303
+ var comp = try Compilation.init(.testing);
2304
+ comp.gpa = allocator;
2278
2305
  defer comp.deinit();
2279
2306
 
2280
2307
  _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n");
@@ -2320,7 +2347,8 @@ test "addSourceFromBuffer - exhaustive check for carriage return elimination" {
2320
2347
  var buf: [alphabet.len]u8 = @splat(alphabet[0]);
2321
2348
 
2322
2349
  var diagnostics: Diagnostics = .{ .output = .ignore };
2323
- var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd());
2350
+ var comp = try Compilation.init(.testing);
2351
+ comp.diagnostics = &diagnostics;
2324
2352
  defer comp.deinit();
2325
2353
 
2326
2354
  var source_count: u32 = 0;
@@ -2346,9 +2374,8 @@ test "addSourceFromBuffer - exhaustive check for carriage return elimination" {
2346
2374
  test "ignore BOM at beginning of file" {
2347
2375
  const BOM = "\xEF\xBB\xBF";
2348
2376
  const Test = struct {
2349
- fn run(arena: Allocator, buf: []const u8) !void {
2350
- var diagnostics: Diagnostics = .{ .output = .ignore };
2351
- var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, Io.Dir.cwd());
2377
+ fn run(buf: []const u8) !void {
2378
+ var comp = try Compilation.init(.testing);
2352
2379
  defer comp.deinit();
2353
2380
 
2354
2381
  const source = try comp.addSourceFromBuffer("file.c", buf);
@@ -2357,19 +2384,15 @@ test "ignore BOM at beginning of file" {
2357
2384
  }
2358
2385
  };
2359
2386
 
2360
- var arena_state: std.heap.ArenaAllocator = .init(std.testing.allocator);
2361
- defer arena_state.deinit();
2362
- const arena = arena_state.allocator();
2363
-
2364
- try Test.run(arena, BOM);
2365
- try Test.run(arena, BOM ++ "x");
2366
- try Test.run(arena, "x" ++ BOM);
2367
- try Test.run(arena, BOM ++ " ");
2368
- try Test.run(arena, BOM ++ "\n");
2369
- try Test.run(arena, BOM ++ "\\");
2370
-
2371
- try Test.run(arena, BOM[0..1] ++ "x");
2372
- try Test.run(arena, BOM[0..2] ++ "x");
2373
- try Test.run(arena, BOM[1..] ++ "x");
2374
- try Test.run(arena, BOM[2..] ++ "x");
2387
+ try Test.run(BOM);
2388
+ try Test.run(BOM ++ "x");
2389
+ try Test.run("x" ++ BOM);
2390
+ try Test.run(BOM ++ " ");
2391
+ try Test.run(BOM ++ "\n");
2392
+ try Test.run(BOM ++ "\\");
2393
+
2394
+ try Test.run(BOM[0..1] ++ "x");
2395
+ try Test.run(BOM[0..2] ++ "x");
2396
+ try Test.run(BOM[1..] ++ "x");
2397
+ try Test.run(BOM[2..] ++ "x");
2375
2398
  }
@@ -24,21 +24,21 @@ pub const Message = struct {
24
24
  @"fatal error",
25
25
  };
26
26
 
27
- pub fn write(msg: Message, t: std.Io.Terminal, details: bool) std.Io.Terminal.SetColorError!void {
28
- const w = t.writer;
29
- try t.setColor(.bold);
27
+ pub fn write(msg: Message, term: std.Io.Terminal, details: bool) std.Io.Terminal.SetColorError!void {
28
+ const w = term.writer;
29
+ try term.setColor(.bold);
30
30
  if (msg.location) |loc| {
31
31
  try w.print("{s}:{d}:{d}: ", .{ loc.path, loc.line_no, loc.col });
32
32
  }
33
33
  switch (msg.effective_kind) {
34
- .@"fatal error", .@"error" => try t.setColor(.bright_red),
35
- .note => try t.setColor(.bright_cyan),
36
- .warning => try t.setColor(.bright_magenta),
34
+ .@"fatal error", .@"error" => try term.setColor(.bright_red),
35
+ .note => try term.setColor(.bright_cyan),
36
+ .warning => try term.setColor(.bright_magenta),
37
37
  .off => unreachable,
38
38
  }
39
39
  try w.print("{s}: ", .{@tagName(msg.effective_kind)});
40
40
 
41
- try t.setColor(.white);
41
+ try term.setColor(.white);
42
42
  try w.writeAll(msg.text);
43
43
  if (msg.opt) |some| {
44
44
  if (msg.effective_kind == .@"error" and msg.kind != .@"error") {
@@ -56,17 +56,17 @@ pub const Message = struct {
56
56
 
57
57
  if (!details or msg.location == null) {
58
58
  try w.writeAll("\n");
59
- try t.setColor(.reset);
59
+ try term.setColor(.reset);
60
60
  } else {
61
61
  const loc = msg.location.?;
62
62
  const trailer = if (loc.end_with_splice) "\\ " else "";
63
- try t.setColor(.reset);
63
+ try term.setColor(.reset);
64
64
  try w.print("\n{s}{s}\n", .{ loc.line, trailer });
65
65
  try w.splatByteAll(' ', loc.width);
66
- try t.setColor(.bold);
67
- try t.setColor(.bright_green);
66
+ try term.setColor(.bold);
67
+ try term.setColor(.bright_green);
68
68
  try w.writeAll("^\n");
69
- try t.setColor(.reset);
69
+ try term.setColor(.reset);
70
70
  }
71
71
  try w.flush();
72
72
  }
@@ -199,6 +199,10 @@ pub const Option = enum {
199
199
  @"pragma-once-outside-header",
200
200
  @"underlying-atomic-qualifier-ignored",
201
201
  @"underlying-cv-qualifier-ignored",
202
+ @"bounds-attributes-redundant",
203
+ @"file-name-extension",
204
+ @"base-file-extension",
205
+ @"include-level-extension",
202
206
 
203
207
  /// GNU extensions
204
208
  pub const gnu = [_]Option{
@@ -541,11 +545,11 @@ fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void {
541
545
 
542
546
  switch (d.output) {
543
547
  .ignore => {},
544
- .to_writer => |t| {
545
- var new_mode = t.mode;
546
- if (d.color == false) new_mode = .no_color;
547
- if (d.color == true and new_mode == .no_color) new_mode = .escape_codes;
548
- msg.write(.{ .writer = t.writer, .mode = new_mode }, d.details) catch {
548
+ .to_writer => |terminal| {
549
+ var mode = terminal.mode;
550
+ if (d.color == false) mode = .no_color;
551
+ if (d.color == true and mode == .no_color) mode = .escape_codes;
552
+ msg.write(.{ .mode = mode, .writer = terminal.writer }, d.details) catch {
549
553
  return error.FatalError;
550
554
  };
551
555
  },